From 4461048df8b7109fbd1e821363453e677541fb77 Mon Sep 17 00:00:00 2001 From: james_sherring Date: Sun, 11 Jan 2004 20:33:39 +0000 Subject: [PATCH] support lines with text (e.g. drive-time regions); translate closed-polygons for import/export; export circles & ovals; support long pushpin notes; import groundspeak types with different symbols; various minor fixes; general clean-up; --- st2gpx/src/ToDo.txt | 4 +- st2gpx/src/annotations.c | 113 ++++++++-- st2gpx/src/annotations.h | 84 +------ st2gpx/src/bugs.txt | 3 + st2gpx/src/contents.c | 280 ++++++----------------- st2gpx/src/contents.h | 181 ++------------- st2gpx/src/debug.c | 329 +-------------------------- st2gpx/src/gpx.h | 19 +- st2gpx/src/history.txt | 7 + st2gpx/src/journey.c | 58 ++--- st2gpx/src/journey.h | 61 ++--- st2gpx/src/nannol.c | 36 ++- st2gpx/src/ppinutil.c | 88 +------- st2gpx/src/ppinutil.h | 50 +---- st2gpx/src/properties.c | 16 +- st2gpx/src/properties.h | 15 +- st2gpx/src/pushpins.cpp | 76 ++++--- st2gpx/src/pushpins.h | 3 +- st2gpx/src/readgpx.c | 10 +- st2gpx/src/readmpst.c | 3 +- st2gpx/src/st2gpx.c | 155 ++++++++----- st2gpx/src/st2gpx.dsp | 220 ------------------ st2gpx/src/st2gpx.h | 36 +-- st2gpx/src/st2gpx.sln | 21 ++ st2gpx/src/st2gpx.vcproj | 472 +++++++++++++++++++++++++++++++++++++++ st2gpx/src/writegpx.c | 152 +++++++++++-- st2gpx/src/writepcx.c | 13 +- 27 files changed, 1154 insertions(+), 1351 deletions(-) delete mode 100644 st2gpx/src/st2gpx.dsp create mode 100644 st2gpx/src/st2gpx.sln create mode 100644 st2gpx/src/st2gpx.vcproj diff --git a/st2gpx/src/ToDo.txt b/st2gpx/src/ToDo.txt index c3ab5e37b..37d9669bd 100644 --- a/st2gpx/src/ToDo.txt +++ b/st2gpx/src/ToDo.txt @@ -5,10 +5,8 @@ To do: option to show ppin names/info on import center and size map on annotations. - Get lat & lon for journey route points not matched to pushpins Get point info for non-line annotations, e.g. text boxes. import route as s&t route (Journey), i.e. not just as a line. - fix overuse of realloc support unicode names (remove str2ascii) different colours for imported routes & tracks @@ -21,6 +19,8 @@ To do: support drive-time zones in annotations stream? + fix ppin import for longer renderdata + Still to test: * various versions, esp import * multiple imports diff --git a/st2gpx/src/annotations.c b/st2gpx/src/annotations.c index e737ba805..2e7ef2874 100644 --- a/st2gpx/src/annotations.c +++ b/st2gpx/src/annotations.c @@ -1,7 +1,8 @@ /* annotations.c - Extract data from MS Streets & Trips .est and Autoroute .axe files in GPX format. + Extract data from MS Streets & Trips .est, Autoroute .axe + and Mapoint .ptm files in GPX format. Copyright (C) 2003 James Sherring, james_sherring@yahoo.com @@ -34,9 +35,13 @@ #include "gpx.h" #include "st2gpx.h" #include "pushpins.h" - #include "annotations.h" +#ifdef EXPLORE +#include "explore.h" +#endif + + // std_anotfile_header[8,9] are variable (number of annotations) char std_annotfile_header[12] // num annots = {0x34, 0x12, 0x00, 0x2d, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00}; @@ -91,7 +96,7 @@ char * annot_type_name[4]={"Line", "Oval", "Textbox", "Circle"}; // double magic2=0x10000; /* -typedef struct annotationbuf +struct annotationbuf { int annot_num; int flags; // bit fields in first byte @@ -107,7 +112,7 @@ typedef struct annotationbuf int joinflag; // 0 line does not join, 1, joins. Not sure what large balues for non-lines mean - xscale? char unkn4; // y-scale? int num_points; // different meaning for non-lines -} structannotationbuf; +}; */ @@ -122,6 +127,7 @@ struct annot_rec * annot_rec_new() nw->text = NULL; nw->line_points=0; nw->line_offset=0; + nw->is_closed_line_flag=0; return nw; } @@ -165,6 +171,7 @@ void annotations_delete(struct annotations * annots) } struct gpxpt* gpx_get_point(char* buf) +//struct gpxpt* gpx_get_point(struct annot_line_point* bufpt) // Convert the 12-byte location structure in annotations stream to GPS coordinates. { struct gpxpt * pt = gpxpt_new(); @@ -183,6 +190,10 @@ struct gpxpt* gpx_get_point(char* buf) y= *(float *)(buf + 4); z= *(float *)(buf + 8); +// x=bufpt->x; +// y=bufpt->y; +// z=bufpt->z; + //printf("gpx_get_point x=%f y=%f z=%f\n",x,y,z); pt->lat = atan2(z,sqrt(pow(x,2)+ pow(y,2)))*180/M_PI; pt->lon = atan2(y,x)*180/M_PI; @@ -192,6 +203,24 @@ struct gpxpt* gpx_get_point(char* buf) return pt; } +void print_annot_rec(struct annot_rec * rec) +{ + int bit_flags = *(int*)(rec->buf + 8); + char* rec_type = NULL; + + if (rec->type<4) + rec_type =annot_type_name[rec->type]; + + printf("Got annotation id %d, of type %s, %d line points", + rec->annot_num, rec_type, rec->line_points); + if(rec->text !=NULL) + printf(" and text '%s'", rec->text); + printf("\n"); + if (opts.verbose_flag > 4) + printf("(type=%d) text length %d, bitflags %#x buf length %d\n", + rec->type, rec->text_length, bit_flags, rec->length); +} + struct annot_rec * read_annot_rec(FILE* annot_in_file, int version) { int status; @@ -226,7 +255,7 @@ struct annot_rec * read_annot_rec(FILE* annot_in_file, int version) } // ********************** - // Read the record header, up to begining of possible text + // Read the record header // ********************** rec->buf = (char*)xmalloc(head_len); @@ -235,13 +264,14 @@ struct annot_rec * read_annot_rec(FILE* annot_in_file, int version) status = readbytes(annot_in_file, rec->buf, head_len); if (status!=head_len) { - //FIXME -// gpx_write_file_trailer(gpx_out_file); - // exit(1) // should do some cleaning up here return rec; } +#ifdef EXPLORE + print_f_annotation_line_header(rec->buf, head_len, version); +#endif + rec->type = *(int*)(rec->buf+ANNOT_RECOS_TYPE); if (rec->type > 3 ) { @@ -253,10 +283,35 @@ struct annot_rec * read_annot_rec(FILE* annot_in_file, int version) rec->annot_num = *(int*)(rec->buf+ANNOT_RECOS_ANUM); // FIXME kludge, fit into the framework bit_flags = *(int*)(rec->buf + 8); - rec->text_length = *(int*)(rec->buf+text_len_offset); + rec->text_length = *(unsigned int*)(rec->buf + text_len_offset); + + // *********************** + // Read extra for the text + // *********************** + + // There can be text for lines! + // This reads the extra part of annot+headfor the text, + // but not the actual text + + rec->buf = (char*)realloc(rec->buf, head_len + 2*(rec->text_length)); + // This read can fail because I have miscalculated size or number of records + // So exit gracefully + status = readbytes(annot_in_file, rec->buf + head_len, 2*(rec->text_length)); + if (status != 2*(rec->text_length)) + { + // should do some cleaning up here + return rec; + } + head_len += 2*(rec->text_length); + line_offset += 2*(rec->text_length); + + // ****************************** + // Now we can get num line points + // ****************************** + rec->line_points=0; if (rec->type == ANNOT_TYPE_LINE) - rec->line_points = *(int*)(rec->buf+head_len-4); + rec->line_points = *(unsigned int*)(rec->buf + head_len - 4 ); // *************************** // Calculate the record length @@ -267,11 +322,13 @@ struct annot_rec * read_annot_rec(FILE* annot_in_file, int version) rec->length += 4; // FIXME This is a kludge + // **** Should use c_shape_points + // c_shape_points = 33 instead of 61, so file is 12*(61-33)=336 if (opts.st_version_num>10) { - if ( (rec->type == 1) || (rec->type == 4) ) + if ( (rec->type == ANNOT_TYPE_OVAL) || (rec->type == ANNOT_TYPE_CIRCLE) ) { - printf("Fudge: shortening 336 bytes from oval record length, but I dont know why.\n"); + //printf("Fudge: shortening 336 bytes from oval record length, but I dont know why.\n"); (rec->length) -= 336; } } @@ -312,6 +369,13 @@ struct annot_rec * read_annot_rec(FILE* annot_in_file, int version) str2ascii(rec->text); } + if (rec->type == ANNOT_TYPE_LINE) + { + rec->is_closed_line_flag = *(unsigned char*)(rec->buf + head_len - 9); + if( (rec->is_closed_line_flag != 0) && (rec->is_closed_line_flag != 1) ) + printf("Unexpected is_closed_line_flag=%d\n", rec->is_closed_line_flag); + } + if (opts.verbose_flag > 1) print_annot_rec(rec); @@ -335,6 +399,15 @@ struct annotations * process_annotations_stream(char* annot_in_file_name) FILE* annot_in_file=NULL; struct annotations * annots = annotations_new(); + int readbyte; +// int max_read_more; +// int readmore; + char* readmorebuf=NULL; +// char* strange=NULL; + float* strange_float=NULL; + struct annot_line_point * strange_pts=NULL; +// struct gpxpt* strange_gpxpt; + annots->header_buf=(char*)xmalloc(ANNOT_FILE_HEAD_LEN); if ((annot_in_file = fopen(annot_in_file_name, "rb")) == NULL) @@ -352,12 +425,15 @@ struct annotations * process_annotations_stream(char* annot_in_file_name) } annots->stream_length += ANNOT_FILE_HEAD_LEN; - for (i=1; i<8; i++) + for (i=1; i<4; i++) if ( annots->header_buf[i] != std_annotfile_header[i] ) printf("Nonstandard annotations file header, header[%i]=0x%x, normal value is 0x%x\n", i, annots->header_buf[i], std_annotfile_header[i] ); annots->version = *(int*)(annots->header_buf+4); + if ((annots->version < 3) || (annots->version > 4)) + printf("Unexpected annotations version %d\n", annots->version); + annots->num_annotations = *(int*)(annots->header_buf+8); annots->annot_list = (struct annot_rec **)xmalloc( @@ -383,8 +459,10 @@ struct annotations * process_annotations_stream(char* annot_in_file_name) { rec = read_annot_rec(annot_in_file, annots->version); +#ifdef EXPLORE if (opts.explore_flag) - explore_annot(rec); + explore_annot(rec, annots->version); +#endif if (rec==NULL) { annots->read_recs_ok_flag = 0; @@ -398,6 +476,8 @@ struct annotations * process_annotations_stream(char* annot_in_file_name) annots->stream_length += rec->length; } + // fudge for White_West_Sts.ptm was here + // Check that we are at the end of annotation file if (read_tail_buff) { @@ -405,14 +485,17 @@ struct annotations * process_annotations_stream(char* annot_in_file_name) status=readbytes(annot_in_file, checkEOF, 4); annots->stream_length += status; if ( (status!=4) || (checkEOF[0]!=0) || (checkEOF[1]!=0) - || (checkEOF[2]!=0) || (checkEOF[3]!=0) || (getc(annot_in_file)!=EOF) ) + || (checkEOF[2]!=0) || (checkEOF[3]!=0) || + (readbyte=getc(annot_in_file)!=EOF) ) { fprintf (stderr, "Did not finish reading annotation file at EOF\n"); + //ungetc(readbyte, annot_in_file); } else annots->read_tail_ok_flag=1; free(checkEOF); } + fclose(annot_in_file); return annots; } diff --git a/st2gpx/src/annotations.h b/st2gpx/src/annotations.h index 0fe4814fd..c70a636b1 100644 --- a/st2gpx/src/annotations.h +++ b/st2gpx/src/annotations.h @@ -1,7 +1,8 @@ /* annotations.h - Extract data from MS Streets & Trips .est and Autoroute .axe files in GPX format. + Extract data from MS Streets & Trips .est, Autoroute .axe + and Mapoint .ptm files in GPX format. Copyright (C) 2003 James Sherring, james_sherring@yahoo.com @@ -46,21 +47,13 @@ extern "C" { #define ANNOT_RECOS_TEXT 24 #define ANNOT_RECOS_LINENUMPOINTS 53 #define ANNOT_RECOS_LINEJOINFLAG 48 -#define ANNOT_RECOS_XSCALE 48 -#define ANNOT_RECOS_YSCALE 52 +#define ANNOT_RECOS_OVAL_POINTOS 136 // 24 for text + 4 + 11ints=44 + 1double=8 + 5pts=60 // + 12*NUM POINTS #define LINE_REC_LEN_V3 57 #define LINE_REC_LEN_V4 61 //??? - -//#define ANNOT_TYPE_LINE 0 -//#define ANNOT_TYPE_OVAL 1 -//#define ANNOT_TYPE_TEXT 2 -//#define ANNOT_TYPE_CIRCLE 3 - -/* -typedef struct annotations_file_head +struct f_annotations_file_head { // always 0x2d001234 unsigned int uiunkn0; @@ -69,63 +62,9 @@ typedef struct annotations_file_head unsigned int version; // number of annotations in the stream unsigned int c_annots; -} tag_annotations_file_head; - -typedef struct annotation_record_header -{ - // 0 = line - // 1 = Oval - // 2 = Textbox/Rectangle - // 3 = Circle - unsigned int type; - // 0x8 = show length - // 0x10 = order before roads - // (order defore other objects depends on file order (last highest) and obj type) - unsigned int bitflags; - int iunkn0; - int iunkn1; - // iunkn2 is only for version 10+ (9+?) - int iunkn2; - unsigned int text_len; - char text[]; - // 0 =black - // 12=blue - unsigned int fill_color; - // 0 = none - // 1 = fill - // + some other high-byte flags? - int fill_flag; - // 0 = black - // 12 = blue - // 0d = yellow - unsigned int line color; - // 20*point size - unsigned int line_width; - // 00=none, - // 01=left, - // 02=right, - // 03=both; - int arrow_type; - int iunkn3; - // 01 is a joined line: the first & last points are joined - // 00 is a line-type - int closed_flag; - char cunkn0; - // number of points in the line - char c_line_points; - struct point_rec[]; -} tag_annotation_header; - -struct annot_line_point -{ - float x; - float y; - float z; -} - -*/ +} ; -typedef struct annot_rec +struct annot_rec { // ANNOT_TYPE_ int type; @@ -135,15 +74,16 @@ typedef struct annot_rec int text_length; char* text; int line_points; - // Pointer to the line-points data in buf, + // Pointer to the line-points data in buf, // because it moves with different file formats. int line_offset; -} tag_annot_rec; + unsigned char is_closed_line_flag; +}; struct annot_rec * annot_rec_new(); void annot_rec_delete(struct annot_rec * annot_rec); -typedef struct annotations +struct annotations { int num_annotations; int max_annot_num; @@ -155,11 +95,12 @@ typedef struct annotations int stream_length; // This is the annotations version number, as stored in the annotations stream int version; -} tag_annotations; +}; struct annotations * annotations_new(); void annotations_delete(struct annotations * annots); struct gpxpt* gpx_get_point(char* buf); +//struct gpxpt* gpx_get_point(struct annot_line_point* bufpt); extern char std_annotfile_header[ANNOT_FILE_HEAD_LEN]; extern char std_annot_linerec_header_v3[LINE_REC_LEN_V3]; @@ -175,7 +116,6 @@ extern char * st_version[]; struct annotations * process_annotations_stream(char* annot_in_file_name); - #ifdef __cplusplus } #endif diff --git a/st2gpx/src/bugs.txt b/st2gpx/src/bugs.txt index b5861ff63..7e6c4377a 100644 --- a/st2gpx/src/bugs.txt +++ b/st2gpx/src/bugs.txt @@ -19,4 +19,7 @@ Bugs: but "steph's wedding.est" is ok (single space) with input file "Plesivec - Plešivec.gpx" we fail to open the gpx as input + + exception importing gpx with long descriptions + mp2004 imported ppins: dont show info, accessing ballon property crashes mp diff --git a/st2gpx/src/contents.c b/st2gpx/src/contents.c index 513420f34..91d252d91 100644 --- a/st2gpx/src/contents.c +++ b/st2gpx/src/contents.c @@ -1,7 +1,8 @@ /* contents.c - Extract data from MS Streets & Trips .est and Autoroute .axe files in GPX format. + Extract data from MS Streets & Trips .est, Autoroute .axe + and Mapoint .ptm files in GPX format. Copyright (C) 2003 James Sherring, james_sherring@yahoo.com @@ -33,17 +34,9 @@ #include "contents.h" #include "annotations.h" -char* buf2str(char* buf, int strlen) -// make a null-terminated string from a buf -{ - char*str=NULL; - if (strlen==0) - return NULL; - str=(char*)xmalloc(strlen+1); - memcpy(str, buf, strlen); - str[strlen]=0; - return str; -} +#ifdef EXPLORE +#include "explore.h" +#endif struct contents * contents_new() { @@ -51,19 +44,24 @@ struct contents * contents_new() nw->fully_parsed_flag=0; nw->buf_len=0; nw->buf=NULL; - nw->f_conts0=NULL; - nw->f_conts_array=NULL; + nw->conts0_os=0; +//x nw->f_conts0=NULL; + nw->array_os=0; +//x nw->f_conts_array=NULL; nw->f_pcbtext0=NULL; nw->f_text0=NULL; - nw->f_conts1=NULL; + nw->conts1_os=0; +//x nw->f_conts1=NULL; nw->f_text1=NULL; - nw->f_conts2=NULL; + nw->conts2_os=0; +//x nw->f_conts2=NULL; // conts2->count_strings strings. // Strings are not nul-terminated, // but they are prefixed with their length. nw->list_f_pcbtext=NULL; nw->list_f_text=NULL; - nw->f_conts3=NULL; + nw->conts3_os=0; +//x nw->f_conts3=NULL; // the end part of the buffer that has not been interpreted. nw->rest=NULL; return nw; @@ -80,108 +78,12 @@ void contents_delete(struct contents * conts) free(conts); } -void print_f_contents0(struct f_contents0 * conts) -{ - struct gpxpt* map_cent=NULL; - - printf("struct f_contents1:\n"); - printf("usunkn0=%d\n", conts->usunkn0); - printf("map_center_X=%f\n", conts->map_center_X); - printf("map_center_Y=%f\n", conts->map_center_Y); - printf("map_center_Z=%f\n", conts->map_center_Z); - printf("map_scale=%f\n", conts->map_scale); - printf("iunkn0=%d\n", conts->iunkn0); - printf("iunkn1=%d\n", conts->iunkn1); - printf("iunkn2=%d\n", conts->iunkn2); - printf("iunkn3=%d\n", conts->iunkn3); - printf("iunkn4=%d\n", conts->iunkn4); - printf("iunkn5=%d\n", conts->iunkn5); - printf("iunkn6=%d\n", conts->iunkn6); - printf("legend_or_directions=%d\n", conts->legend_or_directions); - printf("iunkn7=%d\n", conts->iunkn7); - printf("iunkn8=%d\n", conts->iunkn8); - printf("iunkn9=%d\n", conts->iunkn9); - printf("usunkn2=%d\n", conts->usunkn2); - printf("iunkn10=%d\n", conts->iunkn10); - printf("iunkn11=%d\n", conts->iunkn11); - debug_pause(); - printf("iunkn12=%d\n", conts->iunkn12); - printf("iunkn13=%d\n", conts->iunkn13); - printf("map_format_pannels=%d\n", conts->map_format_pannels); - printf("iunkn14=%d\n", conts->iunkn14); - printf("map_format_style=%d\n", conts->map_format_style); - printf("iunkn16=%d\n", conts->iunkn16); - printf("map_format_font_size=%d\n", conts->map_format_font_size); - - printf("usunkn4=%d\n", conts->usunkn4); - printf("section_len=%d\n", conts->section_len); - printf("usunkn5=%d\n", conts->usunkn5); - printf("array_len=%d\n", conts->array_len); - - map_cent = gpx_get_point((char*)(&conts->map_center_X)); - printf("Got map center %f %f with scale %f (km?).\n", - map_cent->lat, map_cent->lon, conts->map_scale); - gpxpt_delete(map_cent); - - printf("\n"); - printf("\n"); - debug_pause(); -} -/* contents_array - printf("usunkn6=%d\n", conts->usunkn6); - printf("usunkn7=%d\n", conts->usunkn7); - printf("usunkn8=%d\n", conts->usunkn8); - printf("usunkn9=%d\n", conts->usunkn9); - printf("LastSetId=%d\n", conts->LastSetId); - printf("iunkn18=%d\n", conts->iunkn18); - printf("usunkn10=%d\n", conts->usunkn10); - printf("iunkn19=%d\n", conts->iunkn19); - printf("usunkn11=%d\n", conts->usunkn11); - printf("cbText0=%d\n", conts->cbText0); -*/ - -void print_f_contents1(struct f_contents1 * conts) -{ - printf("struct f_contents1:\n"); - - printf("iunkn20=%d\n", conts->iunkn20); - printf("cbText1=%d\n", conts->cbText1); - - printf("\n"); - debug_pause(); -} - -void print_f_contents2(struct f_contents2 * conts) -{ - printf("struct f_contents1:\n"); - - printf("iunkn21=%d\n", conts->iunkn21); - printf("count_strings=%d\n", conts->count_strings); - - printf("\n"); - debug_pause(); -} - -void print_f_contents3(struct f_contents3 * conts) -{ - printf("struct f_contents3:\n"); - - printf("usunkn15=%d\n", conts->usunkn15); - printf("usunkn16=%d\n", conts->usunkn16); - printf("usunkn17=%d\n", conts->usunkn17); - printf("usunkn18=%d\n", conts->usunkn18); - printf("cbCountryText=%d\n", conts->cbCountryText); - - printf("\n"); - debug_pause(); -} - struct contents * parse_contents_buffer(char* buf, unsigned int buf_len) { struct contents * conts = contents_new(); unsigned int buf_pos=0; - char* temp_str; unsigned int i; + unsigned int numstrings; conts->buf = buf; conts->buf_len=buf_len; @@ -190,57 +92,29 @@ struct contents * parse_contents_buffer(char* buf, unsigned int buf_len) // Parse f_contents0 // ***************** - conts->f_conts0 = (struct f_contents0 *)(conts->buf); - buf_pos += sizeof(struct f_contents0); + //x conts->f_conts0 = (struct f_contents0 *)(conts->buf); + conts->conts0_os=0; + //x buf_pos += sizeof(struct f_contents0); + buf_pos += CONT_RECSZ_C0; + if (buf_pos>(conts->buf_len)) { printf("Oops, ran out of buffer with conts0.\n"); return conts; } - if(opts.explore_flag) - print_f_contents0(conts->f_conts0); - // ************************** // Parse conts->f_conts_array // ************************** - conts->f_conts_array=(unsigned short *)(conts->buf + buf_pos); - buf_pos += conts->f_conts0->array_len; + //conts->f_conts_array=(unsigned short *)(conts->buf + buf_pos); + conts->array_os=buf_pos; + //buf_pos += conts->f_conts0->array_len; + buf_pos += *(unsigned int*)(conts->buf + CONT_RECOS_ARRAY_LEN); if (buf_pos>(conts->buf_len)) { printf("Oops, ran out of buffer with conts array.\n"); return conts; } - if(opts.explore_flag) - { - printf("Dumping Contents array:\n"); - printbuf((char*)(conts->f_conts_array), conts->f_conts0->array_len); - - for(i=0; i< 3; i++) - printf("Array[%d]=%d - unknown meaning\n", i, conts->f_conts_array[i]); - - printf("n:=Array[3]=%d is number of user pushpin sets\n", (conts->f_conts_array)[3]); - -// for(i=0; i< (conts->f_conts_array[3]); i++) -// printf("Array[%d]=%d is SetId for user PushpinSet[%d] \n", -// 4+i, -// conts->f_conts_array[4+i], -// conts->f_conts_array[3] - i -1); - - for(i=0; i< (conts->f_conts_array[3]); i++) - printf("Array[4+n-(%d)]=%d is SetId for user PushpinSet[%d]\n", - i, conts->f_conts_array[3+(conts->f_conts_array[3])-i], i); - - for(i=0; (4 + (conts->f_conts_array[3] +i)) < (conts->f_conts0->array_len)/2 ; i++) - printf("Array[5+n+(%d)]=%d - unknown meaning\n", - i, conts->f_conts_array[4+(conts->f_conts_array[3])+i]); - - debug_pause(); - -// printf("Dumping Contents array tail:\n"); -// printbuf((char*)(conts->f_conts_array + 4 + conts->f_conts_array[3]), -// (conts->f_conts0->array_len)-2*(4 + conts->f_conts_array[3]) ); - } // ************************ // Parse f_cbtext0, f_text0 @@ -261,75 +135,63 @@ struct contents * parse_contents_buffer(char* buf, unsigned int buf_len) printf("Oops, ran out of buffer with text0.\n"); return conts; } - // conts->f_cbtext0 is a *pointer* to text len - if(opts.explore_flag) - { - temp_str=buf2str(conts->f_text0, *(conts->f_pcbtext0)); - printf("Got Text0='%s'\n", temp_str); - free(temp_str); - temp_str=NULL; - } // ***************** // Parse f_contents1 // ***************** - conts->f_conts1 = (struct f_contents1 *)(conts->buf+buf_pos); - buf_pos += sizeof(struct f_contents1); + //x conts->f_conts1 = (struct f_contents1 *)(conts->buf+buf_pos); + conts->conts1_os = buf_pos; + //buf_pos += sizeof(struct f_contents1); + buf_pos += CONT_RECSZ_C1; if (buf_pos>(conts->buf_len)) { printf("Oops, ran out of buffer with conts1.\n"); return conts; } - if(opts.explore_flag) - print_f_contents1(conts->f_conts1); // ************* // Parse f_text1 // ************* conts->f_text1 = (conts->buf)+buf_pos; - buf_pos += conts->f_conts1->cbText1; + //x buf_pos += conts->f_conts1->cbText1; + buf_pos += *(unsigned char *)((conts->buf)+buf_pos-1); if (buf_pos>(conts->buf_len)) { printf("Oops, ran out of buffer with text1.\n"); return conts; } - if(opts.explore_flag) - { - temp_str=buf2str(conts->f_text1, conts->f_conts1->cbText1); - printf("Got Text1='%s'\n", temp_str); - free(temp_str); - temp_str=NULL; - } // ***************** // Parse f_contents2 // ***************** - conts->f_conts2 = (struct f_contents2 *)((conts->buf)+buf_pos); - buf_pos += sizeof(struct f_contents2); + //x conts->f_conts2 = (struct f_contents2 *)((conts->buf)+buf_pos); + conts->conts2_os = buf_pos; + //x buf_pos += sizeof(struct f_contents2); + buf_pos += CONT_RECSZ_C2; if (buf_pos>(conts->buf_len)) { printf("Oops, ran out of buffer with conts2.\n"); return conts; } - if(opts.explore_flag) - print_f_contents2(conts->f_conts2); // *************************************** // Parse list_f_cbtext[] and list_f_text[] // *************************************** - conts->list_f_pcbtext=(unsigned char**)xmalloc((conts->f_conts2->count_strings)*sizeof(unsigned char*)); - conts->list_f_text=(char**)xmalloc((conts->f_conts2->count_strings)*sizeof(char*)); + numstrings = *(unsigned short*)(conts->buf + conts->conts2_os + 4); + //x numstrings = conts->f_conts2->count_strings; + conts->list_f_pcbtext=(unsigned char**)xmalloc(numstrings*sizeof(unsigned char*)); + conts->list_f_text=(char**)xmalloc(numstrings*sizeof(char*)); // initialise just incase we dont make it through the parse loop - for(i=0; i<(conts->f_conts2->count_strings); i++) + for(i=0; ilist_f_pcbtext[i]=NULL; conts->list_f_text[i]=NULL; } - for(i=0; i<(conts->f_conts2->count_strings); i++) + for(i=0; ilist_f_pcbtext[i]=(unsigned char*)(conts->buf+buf_pos); @@ -346,12 +208,6 @@ struct contents * parse_contents_buffer(char* buf, unsigned int buf_len) printf("Oops, ran out of buffer with text%d.\n", i); return conts; } - if(opts.explore_flag) - { - temp_str = buf2str(conts->list_f_text[i], *(conts->list_f_pcbtext[i])); - printf("Got list_text[%d]='%s'\n", i, temp_str); - free(temp_str); - } } // ************************** @@ -366,8 +222,6 @@ struct contents * parse_contents_buffer(char* buf, unsigned int buf_len) printf("Oops, ran out of buffer with pusunkn0.\n"); return conts; } - if(opts.explore_flag) - printf("usunkn0=%d\n", *(conts->pusunkn0) ); if(*(conts->pusunkn0) == 1) { @@ -378,43 +232,34 @@ struct contents * parse_contents_buffer(char* buf, unsigned int buf_len) printf("Oops, ran out of buffer with piunkn1.\n"); return conts; } - if(opts.explore_flag) - printf("iunkn1=%d\n", *(conts->piunkn1) ); } // ***************** - // Parse f_contents2 + // Parse f_contents3 // ***************** - conts->f_conts3 = (struct f_contents3 *)(conts->buf+buf_pos); - buf_pos += sizeof(struct f_contents3); + //x conts->f_conts3 = (struct f_contents3 *)(conts->buf+buf_pos); + conts->conts3_os = buf_pos; + //x buf_pos += sizeof(struct f_contents3); + buf_pos += CONT_RECSZ_C3; if (buf_pos>(conts->buf_len)) { printf("Oops, ran out of buffer with conts3.\n"); return conts; } - if(opts.explore_flag) - print_f_contents3(conts->f_conts3); // ***************** // Parse CountryText // ***************** conts->CountryText = (conts->buf)+buf_pos; - buf_pos += conts->f_conts3->cbCountryText; + //x buf_pos += conts->f_conts3->cbCountryText; + buf_pos += *(unsigned char *)((conts->buf)+buf_pos-1); if (buf_pos>(conts->buf_len)) { - printf("Oops, ran out of buffer with text[%d].\n", conts->f_conts2->count_strings); + printf("Oops, ran out of buffer with country text.\n"); return conts; } - if(opts.explore_flag) - { - temp_str=buf2str(conts->CountryText, conts->f_conts3->cbCountryText); - if(opts.explore_flag) - printf("Got CountryText='%s'\n", temp_str); - free(temp_str); - temp_str=NULL; - } if (buf_pos == conts->buf_len) conts->fully_parsed_flag=1; @@ -422,9 +267,15 @@ struct contents * parse_contents_buffer(char* buf, unsigned int buf_len) { printf("Unexpected %d bytes of contents buffer still remaining.\n", (conts->buf_len)-buf_pos); - printbuf((conts->buf)+buf_pos, (conts->buf_len)-buf_pos); + if(opts.verbose_flag > 4) + printbuf((conts->buf)+buf_pos, (conts->buf_len)-buf_pos); } +#ifdef EXPLORE + if (opts.explore_flag) + print_contents(conts); +#endif + return conts; } @@ -444,7 +295,9 @@ struct contents * read_contents(char* conts_file_name) if ((conts_file = fopen(conts_file_name, "rb")) == NULL) { fprintf(stderr, "Cannot open property file %s\n", conts_file_name); - return NULL; + debug_pause(); + exit(3); + //return NULL; } if ((readbyte = getc(conts_file))!=EOF) @@ -462,7 +315,8 @@ struct contents * read_contents(char* conts_file_name) } fclose(conts_file); - printf("Read %d bytes in contents stream %s\n", buf_pos, conts_file_name); + if (opts.verbose_flag>2) + printf("Read %d bytes in contents stream %s\n", buf_pos, conts_file_name); if (opts.verbose_flag>4) { printbuf(buf, buf_pos); @@ -512,7 +366,8 @@ struct contents * contents_insert_ppinset(struct contents * old_conts, unsigned nw_buf = (char *)xmalloc(nw_buf_len); // insert after f_conts_array[3], ie at f_conts_array+4 - insert_position = ((char*)(old_conts->f_conts_array+4)-(old_conts->buf)); + //x insert_position = ((char*)(old_conts->f_conts_array+4)-(old_conts->buf)); + insert_position = old_conts->array_os + 8; memcpy(nw_buf, old_conts->buf, insert_position); memcpy(nw_buf + insert_position, &newSetId, sizeof(unsigned short)); @@ -521,12 +376,18 @@ struct contents * contents_insert_ppinset(struct contents * old_conts, unsigned old_conts->buf_len - insert_position); // set the size of the contents aray - arraylen_os = (char*)&(old_conts->f_conts0->array_len) - old_conts->buf; + //x arraylen_os = (char*)&(old_conts->f_conts0->array_len) - old_conts->buf; + arraylen_os = old_conts->array_os - 4; *(nw_buf + arraylen_os) += sizeof(unsigned short); // increase the number of pushpin sets in f_conts_array[3] *(nw_buf + insert_position - sizeof(unsigned short)) +=1; + // increase section length + *(nw_buf + CONT_RECOS_SECT_LEN) +=2; + // increase iunkn20 + // *(int*)(nw_buf + old_conts->conts1_os + 2) +=1; + nw_conts=parse_contents_buffer(nw_buf, nw_buf_len); return nw_conts; @@ -553,5 +414,4 @@ void write_contents(struct contents * conts, char* conts_file_name) printf("Wrote %d bytes to new contents stream in %s\n", conts->buf_len, conts_file_name); fclose(conts_out_file); - } \ No newline at end of file diff --git a/st2gpx/src/contents.h b/st2gpx/src/contents.h index 3a3064281..6e71068a4 100644 --- a/st2gpx/src/contents.h +++ b/st2gpx/src/contents.h @@ -1,7 +1,8 @@ /* contents.h - Extract data from MS Streets & Trips .est and Autoroute .axe files in GPX format. + Extract data from MS Streets & Trips .est, Autoroute .axe + and Mapoint .ptm files in GPX format. Copyright (C) 2003 James Sherring, james_sherring@yahoo.com @@ -28,174 +29,31 @@ extern "C" { #endif -typedef struct f_contents0 -{ - // @ 00 - unsigned short usunkn0; // 0c 00 - float map_center_X; - float map_center_Y; - float map_center_Z; - // in km? - float map_scale; - // @ 12 - int iunkn0; // 00 00 00 00 - // next two are interesting when there are ppins imported from a file - // got 180213657 = ABDD799 - // and -1073143305 = C00921F7 - int iunkn1; - int iunkn2; - int iunkn3; // 20 03 00 00 - // @ 22 - int iunkn4; // 01 00 00 00 - int iunkn5; // 06 00 00 00 - int iunkn6; // c4 09 00 00 - // 0=legend/route directions if - // 1=no legend - // (related to iunkn13) - unsigned short legend_or_directions; // 00 00 / 01 00 - // @ 30 - int iunkn7; // 01 00 00 00 - int iunkn8; // 06 00 00 00 - int iunkn9; // e4 0c 00 00 for eur8, c4 09 00 00 for usa9 - unsigned short usunkn2; // 00 00 - int iunkn10; // 1 - // @ 42 - int iunkn11; // 06 00 00 00 - int iunkn12; // XX XX 00 00 - unsigned short iunkn13; // 00 00 - - // Does not seem to match these values... - //GeoPaneState Value Description - //geoPaneLegend 0 Legend is displayed - //geoPaneNearbyPlaces 2 Find Nearby Places pane is displayed - //geoPaneNone 3 Only the map is displayed - //geoPaneRoutePlanner 1 Route Planner pane is displayed - //geoPaneTerritory 4 Territory Manager pane is displayed - - // 0=no legend or show route directions ( iunkn6) - // 1=normal - // 2=route planner - // 4=find nearby places - int map_format_pannels; - // @ 50 - int iunkn14; // 1 0 4 0 - -// GeoMapStyle Value Description -// geoMapStyleData 2 Data map -// geoMapStylePolitical 4 Political map -// geoMapStyleRoad 0 Road map -// geoMapStyleRoadData 1 Road and data map -// geoMapStyleTerrain 3 Terrain map - - // 0 = Road - // 3 = Terrain - // 4 = Political - int map_format_style; - int iunkn16; // 1 0 4 0 - // 0-4, - // 0=largest - // 4=smallest - int map_format_font_size; // 03 00 00 00 - // @ 60 - unsigned short usunkn4; //03 00 - //length of section from here until end of EUR/USA string - int section_len; - unsigned short usunkn5; // 03 00 - // array_len = 0x14 + 2*num ppin sets - // if array_len=0x14, str1@81. if array_len=0x16 str1@83 - unsigned int array_len; // xx 00 00 00 (14/16) -} tag_f_contents0; - -/* -typedef struct f_contents_array -{ - unsigned short usunkn6; // 03 00 - unsigned short usunkn7; // 02/01 00 - // @ 70 - unsigned short usunkn8; // 00 00 - // number of user ppin sets - unsigned short usunkn9; // 00/01 00 (0 for empty, 1 for ppins?) - // from UserData/GEODB_LastId/LastSetId - // note the size mismatch: short/long - unsigned short LastSetId; - unsigned short usunkn9_1; // 0 - unsigned short usunkn9_2; // 0 - unsigned short usunkn10; // 0 - unsigned short usunkn10_1; // 0 - unsigned short usunkn10_2; // 0 - int iunkn19; // 3 - // @ 80 - unsigned short usunkn11; // 0 -} tag_f_contents_array; -*/ - -// + unsigned char cbText0; -// + cbText0 bytes of text - -// @ 8b - -typedef struct f_contents1 -{ - int iunkn20; // 00 00 00 00/ff ff ff ff - unsigned char cbText1; -} tag_f_contents1; - -// + cbText1 bytes of text -// @ 98 -typedef struct f_contents2 -{ - int iunkn21; // ff ff ff ff - // This is a count of strings before contents3 - unsigned short count_strings; // 3 -} tag_f_contents2; - -// unsigned char cbText2; -// + cbText2 bytes of text -// @ a6 -// + unsigned char cbText3 -// + cbText3 bytes of text -// @ ae -// + optional ? unsigned char cbText4 -// + optional ? cbText4 bytes of text -// @ b7 - -//+ unsigned short usunkn14; -// + int (if usunkn14) - -typedef struct f_contents3 -{ - unsigned short usunkn15; - unsigned short usunkn16; - unsigned short usunkn17; - unsigned short usunkn18; - // FIXME + an extra short for usa9, + 2 extra shorts for usa10 - unsigned char cbCountryText; -} tag_f_contents3; - -// + cbText5 bytes of text: USA/EUR - -// more for USA9 -// + int -// + unsigned char cbText6 -// + cbText6 bytes of text -// + unsigned char cbText7 -// + cbText7 bytes of text : path to html: html export file? -// + 0x40 bytes +#define CONT_RECSZ_C0 108 +#define CONT_RECOS_SECT_LEN 98 +#define CONT_RECOS_ARRAY_LEN 104 +#define CONT_RECSZ_C1 5 +#define CONT_RECSZ_C2 6 +#define CONT_RECSZ_C3 9 -typedef struct contents +struct contents { int fully_parsed_flag; unsigned int buf_len; // The data as read from the contents stream. char* buf; - struct f_contents0 * f_conts0; - unsigned short * f_conts_array; + int conts0_os; + //x struct f_contents0 * f_conts0; + int array_os; + //x unsigned short * f_conts_array; unsigned char * f_pcbtext0; char* f_text0; - struct f_contents1 * f_conts1; + int conts1_os; + //x struct f_contents1 * f_conts1; char* f_text1; - struct f_contents2 * f_conts2; + int conts2_os; + //x struct f_contents2 * f_conts2; // Lengths for conts2->count_strings number of strings. // Note that this is array of *pointers* to string-length unsigned char ** list_f_pcbtext; @@ -207,11 +65,12 @@ typedef struct contents unsigned short * pusunkn0; // Only when usunkn0=1 ??? int * piunkn1; - struct f_contents3 * f_conts3; + int conts3_os; + //x struct f_contents3 * f_conts3; char * CountryText; // The end part of the buffer that has not been interpreted. char* rest; -} tag_contents; +} ; struct contents * read_contents(char* conts_file_name); struct contents * contents_insert_ppinset(struct contents * old_conts, unsigned short newSetId); diff --git a/st2gpx/src/debug.c b/st2gpx/src/debug.c index 62a11a5be..e640d8282 100644 --- a/st2gpx/src/debug.c +++ b/st2gpx/src/debug.c @@ -1,7 +1,8 @@ /* debug.c - Extract data from MS Streets & Trips .est and Autoroute .axe files in GPX format. + Extract data from MS Streets & Trips .est, Autoroute .axe + and Mapoint .ptm files in GPX format. Copyright (C) 2003 James Sherring, james_sherring@yahoo.com @@ -65,332 +66,6 @@ void printbuf(char* buf, int len) printf("\n\n"); } -void printpoints(char* buf, int numpts) -{ - int i; - struct gpxpt* pt; - printf("Latitude Longitude Height"); - printf("\n"); - printf("--------------------------\n"); - for(i=0; ilat, pt->lon, pt->elevation); - gpxpt_delete(pt); - } - printf("\n\n"); -} - -void explore_annot(struct annot_rec * rec) -{ -} - -void print_f_jour_header(struct f_jour_header * head) -{ - printf("struct f_jour_header:\n"); - printf("iunkn0 %x=%d\n", head->iunkn0, head->iunkn0); - printf("iunkn1 %x=%d\n", head->iunkn1, head->iunkn1); - printf("iunkn2 %x=%d\n", head->iunkn2, head->iunkn2); - printf("iunkn3 %x=%d\n", head->iunkn3, head->iunkn3); - printf("cpoints %x=%d\n", head->cpoints, head->cpoints); - printf("iunkn4 %x=%d\n", head->iunkn4, head->iunkn4); - printf("iunkn5 %x=%d\n", head->iunkn5, head->iunkn5); - printf("iunkn6 %x=%d\n", head->iunkn6, head->iunkn6); -} - -void print_f_jour_pt_head(struct f_jour_pt_head * pt_head) -{ -// double x; - printf("struct f_jour_pt_head:\n"); - printf("UdId %d\n", pt_head->UdId); - printf("stop_dur_secs %d\n", pt_head->stop_dur_secs); - printf("iunkn0 %#x=%d\n", pt_head->iunkn0, pt_head->iunkn0); - printf("sched_arrive_flag %d\n", pt_head->sched_arrive_flag); - printf("sched_depart_flag %d\n", pt_head->sched_depart_flag); - printf("arrive_time_secs %d\n", pt_head->arrive_time_secs); - printf("depart_time_secs %d\n", pt_head->depart_time_secs); - printf("iunkn1 %#x=%d\n", pt_head->iunkn1, pt_head->iunkn1); -// x = pt_head->unkn_scaled_lon; -// x = x*360/0x10000; -// x = x/0x10000; - printf("scaled_lon %d gives lon %f\n", - pt_head->scaled_lon, scaled2deg(pt_head->scaled_lon)); -// x = (pt_head->unkn_scaled_lat*360/0x10000); -// x = x/0x10000; - printf("scaled_lat %d gives lat %f\n", - pt_head->scaled_lat, scaled2deg(pt_head->scaled_lat)); - printf("cbtext1 %d\n",pt_head->cbtext1); - printbuf((char*)pt_head, sizeof(struct f_jour_pt_head)); -} - -void print_f_jour_pt_tail(struct f_jour_pt_tail * pt_tail) -{ - printf("struct f_jour_pt_tail: \n"); - printf("route_rd_pref %x\n",pt_tail->route_rd_pref); - printf("iunkn0 %x=%d\n", pt_tail->iunkn0, pt_tail->iunkn0); - printf("iunkn1 %x=%d\n", pt_tail->iunkn1, pt_tail->iunkn1); - printf("iunkn2 %x=%d\n", pt_tail->iunkn2, pt_tail->iunkn2); - printf("iunkn3 %x=%d\n", pt_tail->iunkn3, pt_tail->iunkn3); - printf("road_id %x=%d\n", pt_tail->road_id, pt_tail->road_id); - printf("dist_along_rd_frac %lf \n", pt_tail->dist_along_rd_frac); - - printf("rd_arrive_sc_lat %d gives lat %f\n", - pt_tail->rd_arrive_sc_lat, scaled2deg(pt_tail->rd_arrive_sc_lat)); - - printf("rd_arrive_sc_lon %d gives lat %f\n", - pt_tail->rd_arrive_sc_lon, scaled2deg(pt_tail->rd_arrive_sc_lon)); - - printf("rd_depart_sc_lat %d gives lat %f\n", - pt_tail->rd_depart_sc_lat, scaled2deg(pt_tail->rd_depart_sc_lat)); - - printf("rd_depart_sc_lon %d gives lat %f\n", - pt_tail->rd_depart_sc_lon, scaled2deg(pt_tail->rd_depart_sc_lon)); - - printf("iunkn8 %x=%d\n", pt_tail->iunkn8, pt_tail->iunkn8); - printf("iunkn9 %x=%d\n", pt_tail->iunkn9, pt_tail->iunkn9); - printf("iunkn10 %x=%d\n", pt_tail->iunkn10, pt_tail->iunkn10); - printf("iunkn11 %x=%d\n", pt_tail->iunkn11, pt_tail->iunkn11); - printf("iunkn12 %x=%d\n", pt_tail->iunkn12, pt_tail->iunkn12); - printf("iunkn13 %x=%d\n", pt_tail->iunkn13, pt_tail->iunkn13); - printf("iunkn14 %x=%d\n", pt_tail->iunkn14, pt_tail->iunkn14); - - printbuf((char*)pt_tail, sizeof(struct f_jour_pt_tail)); -} - -void print_f_jour_opts(struct f_jour_opts * jopts) -{ - printf("struct f_jour_opts:\n"); - - printf("siunkn0 %d\n", jopts->siunkn0); - printf("funkn0 %f\n", jopts->funkn0); - printf("toll_rd_pref %lf\n", jopts->toll_rd_pref); - printf("motorway_pref %lf\n", jopts->motorway_pref); - printf("major_rd_pref %lf\n", jopts->major_rd_pref); - printf("minor_rd_pref %lf\n", jopts->minor_rd_pref); - printf("ferry_pref %lf\n", jopts->ferry_pref); - printf("iunkn0 %d\n", jopts->iunkn0); - printf("iunkn1 %d\n", jopts->iunkn1); - printf("iunkn2 %d\n", jopts->iunkn2); - printf("fuel_price %lf\n", jopts->fuel_price); - printf("iunkn3 %d\n", jopts->iunkn3); - printf("fuel_price_unit %d\n", jopts->fuel_price_unit); - printf("iunkn4 %d\n", jopts->iunkn4); - printf("tank_capacity %lf\n", jopts->tank_capacity); - printf("tank_capacity_units %d\n", jopts->tank_capacity_units); - printf("tank_start_level %lf\n", jopts->tank_start_level); - printf("tank_warn_level %lf\n", jopts->tank_warn_level); - printf("iunkn5 %d\n", jopts->iunkn5); - printf("fuel_use_city %lf\n", jopts->fuel_use_city); - printf("fuel_use_city_unit %d\n", jopts->fuel_use_city_unit); - printf("iunkn6 %d\n", jopts->iunkn6); - printf("fuel_use_mway %lf\n", jopts->fuel_use_mway); - printf("fuel_use_mway_unit %d\n", jopts->fuel_use_mway_unit); - printf("iunkn7 %d\n", jopts->iunkn7); - printf("mway_speed %f\n", jopts->mway_speed); - printf("mway_speed_unit %d\n", jopts->mway_speed_unit); - printf("iunkn9 %d\n", jopts->iunkn9); - printf("lim_acc_speed %f\n", jopts->lim_acc_speed); - printf("lim_acc_speed_unit %d\n", jopts->lim_acc_speed_unit); - printf("iunkn11 %d\n", jopts->iunkn11); - printf("maj_rd_speed %f\n", jopts->maj_rd_speed); - printf("maj_rd_speed_unit %d\n", jopts->maj_rd_speed_unit); - printf("iunkn13 %d\n", jopts->iunkn13); - printf("min_rd_speed %f\n", jopts->min_rd_speed); - printf("min_rd_speed_unit %d\n", jopts->min_rd_speed_unit); - printf("iunkn15 %d\n", jopts->iunkn15); - printf("street_speed %f\n", jopts->street_speed); - printf("street_speed_unit %d\n", jopts->street_speed_unit); - printf("iunkn17 %d\n", jopts->iunkn17); - printf("iunkn18 %d\n", jopts->iunkn18); - printf("funkn1 %f\n", jopts->funkn1); - printf("iunkn19 %d\n", jopts->iunkn19); - printf("iunkn20 %d\n", jopts->iunkn20); - printf("iunkn21 %d\n", jopts->iunkn21); - printf("funkn2 %f\n", jopts->funkn2); - printf("iunkn22 %d\n", jopts->iunkn22); - printf("iunkn23 %d\n", jopts->iunkn23); - printf("iunkn24 %d\n", jopts->iunkn24); - printf("funkn3 %f\n", jopts->funkn3); - printf("iunkn25 %d\n", jopts->iunkn25); - printf("iunkn26 %d\n", jopts->iunkn26); - printf("iunkn27 %d\n", jopts->iunkn27); - printf("funkn4 %f\n", jopts->funkn4); - printf("iunkn28 %d\n", jopts->iunkn28); - printf("iunkn29 %d\n", jopts->iunkn29); - printf("iunkn30 %d\n", jopts->iunkn30); - printf("funkn5 %f\n", jopts->funkn5); - printf("iunkn31 %d\n", jopts->iunkn31); - printf("iunkn32 %d\n", jopts->iunkn32); - printf("iunkn33 %d\n", jopts->iunkn33); - printf("start_drv_hr %d\n", jopts->start_drv_hr); - printf("start_drv_min %d\n", jopts->start_drv_min); - printf("iunkn34 %d\n", jopts->iunkn34); - printf("end_drv_hr %d\n", jopts->end_drv_hr); - printf("end_drv_min %d\n", jopts->end_drv_min); - printf("fuel_warn_flag %d\n", jopts->fuel_warn_flag); - printf("iunkn35 %d\n", jopts->iunkn35); - printf("fuel_fixed_rate_flag %d\n", jopts->fuel_fixed_rate_flag); - printf("iunkn36 %d\n", jopts->iunkn36); - printf("fuel_cost_dist %d\n", jopts->fuel_cost_dist); - printf("route_flex_secs %d\n", jopts->route_flex_secs); - printf("iunkn37 %d\n", jopts->iunkn37); - printf("rest_flag %d\n", jopts->rest_flag); - printf("rest_dur_secs %d\n", jopts->rest_dur_secs); - printf("rest_interval_secs %d\n", jopts->rest_interval_secs); - - printbuf((char*)jopts, sizeof(struct f_jour_opts)); - printf("\n"); -} - -void print_f_jour_opts_EUR_8(struct f_jour_opts_EUR_8 * jopts) -{ - printf("struct f_jour_opts_EUR_8:\n"); - - printf("iunkn38 %d\n", jopts->iunkn38); - printf("iunkn39 %d\n", jopts->iunkn39); - printf("iunkn40 %d\n", jopts->iunkn40); - printf("iunkn41 %d\n", jopts->iunkn41); - printf("iunkn42 %d\n", jopts->iunkn42); - printf("siunkn1 %d\n", jopts->siunkn1); - printf("route_show_tm %d\n", jopts->route_show_tm); - printf("route_show_dist %d\n", jopts->route_show_dist); - printf("route_show_inst %d\n", jopts->route_show_inst); - printf("route_show_for %d\n", jopts->route_show_for); - printf("route_show_to %d\n", jopts->route_show_to); - printf("route_show_font_size %d\n", jopts->route_show_font_size); - printf("iunkn43 %d\n", jopts->iunkn43); - printf("iunkn44 %d\n", jopts->iunkn44); - printf("count_avoid_regions %d\n", jopts->count_avoid_regions); - - printbuf((char*)jopts, sizeof(struct f_jour_opts_EUR_8)); - printf("\n"); -} - -void print_f_jour_opts_EUR_10(struct f_jour_opts_EUR_10 * jopts) -{ - printf("struct f_jour_opts_EUR_10:\n"); - - printf("iunkn38 %d\n", jopts->iunkn38); - printf("iunkn39 %d\n", jopts->iunkn39); - printf("iunkn40 %d\n", jopts->iunkn40); - printf("iunkn41 %d\n", jopts->iunkn41); - printf("iunkn41 %d\n", jopts->iunkn42); - printf("count_avoid_regions %d\n", jopts->count_avoid_regions); - - printbuf((char*)jopts, sizeof(struct f_jour_opts_EUR_10)); - printf("\n"); -} - -void print_f_jour_opts_USA_8(struct f_jour_opts_USA_8 * jopts) -{ - printf("struct f_jour_opts_USA_8:\n"); - - printf("iunkn38 %d\n", jopts->iunkn38); - printf("iunkn39 %d\n", jopts->iunkn39); - printf("iunkn40 %d\n", jopts->iunkn40); - printf("iunkn41 %d\n", jopts->iunkn41); - printf("iunkn42 %d\n", jopts->iunkn42); - printf("siunkn1 %d\n", jopts->siunkn1); - printf("iunkn43 %d\n", jopts->iunkn43); - printf("iunkn44 %d\n", jopts->iunkn44); - printf("iunkn45 %d\n", jopts->iunkn45); - printf("iunkn46 %d\n", jopts->iunkn46); - printf("iunkn47 %d\n", jopts->iunkn47); - printf("iunkn48 %d\n", jopts->iunkn48); - printf("iunkn49 %d\n", jopts->iunkn49); - printf("count_avoid_regions %d\n", jopts->count_avoid_regions); - - printbuf((char*)jopts, sizeof(struct f_jour_opts_USA_8)); - printf("\n"); -} - -void print_f_jour_opts_USA_10(struct f_jour_opts_USA_10 * jopts) -{ - printf("struct f_jour_opts_USA_10:\n"); - - printf("iunkn38 %d\n", jopts->iunkn38); - printf("iunkn39 %d\n", jopts->iunkn39); - printf("iunkn40 %d\n", jopts->iunkn40); - printf("iunkn41 %d\n", jopts->iunkn41); - printf("iunkn42 %d\n", jopts->iunkn42); - printf("siunkn1 %d\n", jopts->siunkn1); - printf("iunkn43 %d\n", jopts->iunkn43); - printf("iunkn44 %d\n", jopts->iunkn44); - printf("count_avoid_regions %d\n", jopts->count_avoid_regions); - - printbuf((char*)jopts, sizeof(struct f_jour_opts_USA_10)); - printf("\n"); -} - -void print_f_jour_avoid(struct f_jour_avoid * avoid) -{ - struct gpxpt * gpt = gpx_get_point((char*)avoid); - struct point pt; - printf("struct f_jour_avoid:\n"); - - printf("x %f\n", avoid->x); - printf("y %f\n", avoid->y); - printf("z %f\n", avoid->z); - printf("iunkn0 %d\n", avoid->iunkn0); - printf("iunkn1 %d\n", avoid->iunkn1); - printf("iunkn2 %d\n", avoid->iunkn2); - printf("iunkn3 %d\n", avoid->iunkn3); - printf("iunkn4 %d\n", avoid->iunkn4); - printf("iunkn5 %d\n", avoid->iunkn5); - printf("annot_num %d\n", avoid->annot_num); - printf("x,y,z give lat %f and lon %f\n", gpt->lat, gpt->lon); - - pt = grid2latlon(avoid->iunkn1, avoid->iunkn2); - printf("iunkn1, lunkn2 as grid, precision give lat %f and lon %f\n", pt.lat, pt.lon); - pt = grid2latlon(avoid->iunkn2, avoid->iunkn3); - printf("iunkn2, lunkn3 as grid, precision give lat %f and lon %f\n", pt.lat, pt.lon); - pt = grid2latlon(avoid->iunkn3, avoid->iunkn4); - printf("iunkn3, lunkn4 as grid, precision give lat %f and lon %f\n", pt.lat, pt.lon); - - printbuf((char*)avoid, sizeof(struct f_jour_avoid)); - printf("\n"); -} - -void print_f_jour_trailer(struct f_jour_trailer * trailer) -{ - printf("struct f_jour_trailer:\n"); - - printf("iunkn0 %d\n", trailer->iunkn0); - printf("iunkn1 %d\n", trailer->iunkn1); - - printbuf((char*)trailer, sizeof(struct f_jour_trailer)); - printf("\n"); -} - -void print_annot_rec(struct annot_rec * rec) -{ - int bit_flags = *(int*)(rec->buf + 8); - char* rec_type = NULL; - - if (rec->type<4) - rec_type =annot_type_name[rec->type]; - - printf("Got annotation id %d, of type %s, %d line points", - rec->annot_num, rec_type, rec->line_points); - if(rec->text !=NULL) - printf(" and text '%s'", rec->text); - printf("\n"); - if (opts.verbose_flag > 4) - printf("(type=%d) text length %d, bitflags %#x buf length %d\n", - rec->type, rec->text_length, bit_flags, rec->length); -} - -void print_annotations(struct annotations * annots) -{ - int i; - // This is only the main stuff - printf("Annotations list, version=%d, num_annotations=%d, max_annot_num=%d, stream_length=%d\n", - annots->version, annots->num_annotations, - annots->max_annot_num, annots->stream_length); - - for(i=0; inum_annotations; i++) - print_annot_rec(annots->annot_list[i]); -} void debug_show_sizes() { diff --git a/st2gpx/src/gpx.h b/st2gpx/src/gpx.h index a55173cb3..edf15e06f 100644 --- a/st2gpx/src/gpx.h +++ b/st2gpx/src/gpx.h @@ -1,7 +1,8 @@ /* gpx.h - Extract data from MS Streets & Trips .est and Autoroute .axe files in GPX format. + Extract data from MS Streets & Trips .est, Autoroute .axe + and Mapoint .ptm files in GPX format. Copyright (C) 2003 James Sherring, james_sherring@yahoo.com @@ -39,7 +40,7 @@ extern "C" { #define GPX_ELEM_TYPE_DESC 8 #define GPX_ELEM_TYPE_SRC 9 -typedef struct gpxpt +struct gpxpt { double lat; double lon; @@ -54,32 +55,32 @@ typedef struct gpxpt char* url; char* urlname; // more later -} tag_gpxpt; +}; struct gpxpt * gpxpt_new(); void gpxpt_delete(struct gpxpt * pt); struct gpxpt * gpxpt_copy(struct gpxpt * otherpt); -typedef struct gpxrte +struct gpxrte { char* name; struct gpxpt** rtept_list; int rtept_list_count; -} tag_gpxrte; +}; struct gpxrte * gpxrte_new(); void gpxrte_delete(struct gpxrte * rte); -typedef struct gpxtrk +struct gpxtrk { struct gpxpt** trkpt_list; int trkpt_list_count; -} tag_gpxtrk; +} ; struct gpxtrk * gpxtrk_new(); void gpxtrk_delete(struct gpxtrk * trk); -typedef struct gpx_data +struct gpx_data { char* data_source_name; struct gpxpt ** wpt_list; @@ -88,7 +89,7 @@ typedef struct gpx_data int rte_list_count; struct gpxtrk ** trk_list; int trk_list_count; -} tag_gpx_data; +}; struct gpx_data * gpx_data_new(); void gpx_data_delete(struct gpx_data * data); diff --git a/st2gpx/src/history.txt b/st2gpx/src/history.txt index 5e6d20a04..02ff0216f 100644 --- a/st2gpx/src/history.txt +++ b/st2gpx/src/history.txt @@ -31,3 +31,10 @@ Yeah, ok, I am just an amateur at this... 28-11-2003 imports pushpins imports lines to v3 annotations (2002+) 5-12-2003 imports/exports symbols, with custom GPX symbol names +11-12-2003 support lines with text (e.g. drive-time regions) + translate closed-polygons for import/export + export circles & ovals + support long pushpin notes + import groundspeak types with different symbols + various minor fixes + general clean-up diff --git a/st2gpx/src/journey.c b/st2gpx/src/journey.c index 7a1a9619a..da2b612d3 100644 --- a/st2gpx/src/journey.c +++ b/st2gpx/src/journey.c @@ -1,7 +1,8 @@ /* journey.c - Extract data from MS Streets & Trips .est and Autoroute .axe files in GPX format. + Extract data from MS Streets & Trips .est, Autoroute .axe + and Mapoint .ptm files in GPX format. Copyright (C) 2003 James Sherring, james_sherring@yahoo.com @@ -36,9 +37,12 @@ #include "st2gpx.h" #include "pushpins.h" #include "ppinutil.h" - #include "journey.h" +#ifdef EXPLORE +#include "explore.h" +#endif + float scaled2deg(int scaled_deg) // there must be a simple single line calc { @@ -77,11 +81,13 @@ struct journey * journey_new() nw->buf_len=0; nw->buf=NULL; + nw->count_rtepts=0; nw->rtept_list=NULL; nw->jopts_os=0; nw->jopts_eur8_os=0; nw->jopts_usa8_os=0; nw->jopts_usa10_os=0; + nw->count_avoid_regions=0; nw->avoid_os_list=NULL; nw->trailer_os=0; return nw; @@ -129,11 +135,13 @@ struct journey * process_journey_stream (char* jour_in_file_name, struct f_jour_opts_USA_8* opts_usa8; struct f_jour_opts_USA_10* opts_usa10; - printf("Processing Journey stream\n"); + if (opts.verbose_flag>2) + printf("Processing Journey stream\n"); if ((jour_in_file = fopen(jour_in_file_name, "rb")) == NULL) { fprintf(stderr, "Quitting because I cannot open %s\n", jour_in_file_name); + debug_pause(); exit(1); } @@ -152,8 +160,6 @@ struct journey * process_journey_stream (char* jour_in_file_name, printf("got Journey file header with %d waypoints\n", jour->count_rtepts); debug_pause(); - if (opts.explore_flag) - print_f_jour_header((struct f_jour_header*)(jour->buf + jour->header_os)); // an array of jour_rtept jour->rtept_list = (struct jour_rtept *)xmalloc( @@ -175,9 +181,6 @@ struct journey * process_journey_stream (char* jour_in_file_name, } jour->rtept_list[j].pthead_os=jour->buf_len; jour->buf_len += bytes2read; - if (opts.explore_flag) - print_f_jour_pt_head((struct f_jour_pt_head*) - (jour->buf + jour->rtept_list[j].pthead_os)); // read pt text1 bytes2read=((struct f_jour_pt_head*) @@ -199,8 +202,6 @@ struct journey * process_journey_stream (char* jour_in_file_name, str2ascii(jour->rtept_list[j].text1); } - if (opts.explore_flag) - printf("Got text1 %s\n", jour->rtept_list[j].text1); // read pt middle bytes2read=sizeof(struct f_jour_pt_mid); @@ -214,11 +215,6 @@ struct journey * process_journey_stream (char* jour_in_file_name, } jour->rtept_list[j].ptmid_os=jour->buf_len; jour->buf_len += bytes2read; - if (opts.explore_flag) - { - printf("dumping jour->rtept_list[%d].ptmid:\n", j); - printbuf(jour->buf + jour->rtept_list[j].ptmid_os, bytes2read); - } // read pt text2 bytes2read=2*(((struct f_jour_pt_mid*)(jour->buf+jour->rtept_list[j].ptmid_os))->cbtext2); @@ -238,8 +234,6 @@ struct journey * process_journey_stream (char* jour_in_file_name, jour->rtept_list[j].text2[bytes2read+1]=0; jour->buf_len += bytes2read; } - if (opts.explore_flag) - wprintf(L"Got text2 %s\n", jour->rtept_list[j].text2); // read pt tail bytes2read=sizeof(struct f_jour_pt_tail); @@ -253,8 +247,6 @@ struct journey * process_journey_stream (char* jour_in_file_name, } jour->rtept_list[j].pttail_os=jour->buf_len; jour->buf_len += bytes2read; - if (opts.explore_flag) - print_f_jour_pt_tail((struct f_jour_pt_tail*)(jour->buf +jour->rtept_list[j].pttail_os)); pt_head = (struct f_jour_pt_head*)(jour->buf+jour->rtept_list[j].pthead_os); // UdId= ((struct f_jour_pt_head*)(jour->buf+jour->rtept_list[j].pthead_os))->UdId; @@ -317,8 +309,6 @@ struct journey * process_journey_stream (char* jour_in_file_name, } jour->jopts_os=jour->buf_len; jour->buf_len += bytes2read; - if (opts.explore_flag) - print_f_jour_opts((struct f_jour_opts*)(jour->buf + jour->jopts_os)); // read file-version specific journey options if( (opts.st_version_num==8) && (opts.isUSA==0)) @@ -336,12 +326,10 @@ struct journey * process_journey_stream (char* jour_in_file_name, jour->buf_len += bytes2read; opts_eur8=(struct f_jour_opts_EUR_8*)(jour->buf + jour->jopts_eur8_os); jour->count_avoid_regions = opts_eur8->count_avoid_regions; - if (opts.explore_flag) - print_f_jour_opts_EUR_8(opts_eur8); } else if( ( (opts.st_version_num==10) && (opts.isUSA==0) ) - || ( (opts.st_version_num==9) && (opts.isUSA==1) ) - || ( (opts.st_version_num==11) && (opts.isUSA==1) )) + || ( (opts.st_version_num==9) ) + || ( (opts.st_version_num==11) )) { bytes2read=sizeof(struct f_jour_opts_EUR_10); jour->buf=(char*)xrealloc(jour->buf, jour->buf_len+bytes2read); @@ -356,8 +344,6 @@ struct journey * process_journey_stream (char* jour_in_file_name, jour->buf_len += bytes2read; opts_eur10=(struct f_jour_opts_EUR_10*)(jour->buf + jour->jopts_eur10_os); jour->count_avoid_regions = opts_eur10->count_avoid_regions; - if (opts.explore_flag) - print_f_jour_opts_EUR_10(opts_eur10); } else if( (opts.st_version_num==8) && (opts.isUSA) ) { @@ -374,10 +360,8 @@ struct journey * process_journey_stream (char* jour_in_file_name, jour->buf_len += bytes2read; opts_usa8=(struct f_jour_opts_USA_8*)(jour->buf + jour->jopts_usa8_os); jour->count_avoid_regions = opts_usa8->count_avoid_regions; - if (opts.explore_flag) - print_f_jour_opts_USA_8(opts_usa8); } - else if( (opts.st_version_num==10) && (opts.isUSA) ) + else if((opts.st_version_num==10) && (opts.isUSA) ) { bytes2read=sizeof(struct f_jour_opts_USA_10); jour->buf=(char*)xrealloc(jour->buf, jour->buf_len+bytes2read); @@ -392,8 +376,6 @@ struct journey * process_journey_stream (char* jour_in_file_name, jour->buf_len += bytes2read; opts_usa10=(struct f_jour_opts_USA_10*)(jour->buf + jour->jopts_usa10_os); jour->count_avoid_regions = opts_usa10->count_avoid_regions; - if (opts.explore_flag) - print_f_jour_opts_USA_10(opts_usa10); } else printf("I dont yet understand the structure of the Journey options for this file version.\n"); @@ -419,8 +401,6 @@ struct journey * process_journey_stream (char* jour_in_file_name, } jour->avoid_os_list[j]= jour->buf_len; jour->buf_len += bytes2read; - if (opts.explore_flag) - print_f_jour_avoid((struct f_jour_avoid*)(jour->buf + jour->avoid_os_list[j])); } } @@ -436,8 +416,6 @@ struct journey * process_journey_stream (char* jour_in_file_name, } jour->trailer_os=jour->buf_len; jour->buf_len += bytes2read; - if (opts.explore_flag) - print_f_jour_trailer((struct f_jour_trailer*)(jour->buf + jour->trailer_os)); readmore=0; if ((readbyte = getc(jour_in_file))!=EOF) @@ -457,8 +435,14 @@ struct journey * process_journey_stream (char* jour_in_file_name, fclose(jour_in_file); - printf("Finished processing Journey stream.\n"); + if (opts.verbose_flag>2) + printf("Finished processing Journey stream.\n"); fflush(stdout); +#ifdef EXPLORE + if (opts.explore_flag) + print_journey(jour); +#endif + return jour; } diff --git a/st2gpx/src/journey.h b/st2gpx/src/journey.h index 074038429..f750cde49 100644 --- a/st2gpx/src/journey.h +++ b/st2gpx/src/journey.h @@ -1,7 +1,8 @@ /* journey.h - Extract data from MS Streets & Trips .est and Autoroute .axe files in GPX format. + Extract data from MS Streets & Trips .est, Autoroute .axe + and Mapoint .ptm files in GPX format. Copyright (C) 2003 James Sherring, james_sherring@yahoo.com @@ -51,7 +52,7 @@ extern "C" { // * points located by address Vs by mouse Vs by pushpin // * avoid areas // * drag route -typedef struct f_jour_header +struct f_jour_header { int iunkn0; int iunkn1; @@ -61,9 +62,9 @@ typedef struct f_jour_header int iunkn4; int iunkn5; int iunkn6; -} tag_f_jour_header; +}; -typedef struct f_jour_pt_head +struct f_jour_pt_head { // DB prim key for pushpin // 0 if no pushpin @@ -83,20 +84,20 @@ typedef struct f_jour_pt_head int scaled_lon; int scaled_lat; unsigned char cbtext1; -} tag_f_jour_pt_head; +}; // then jour_pt_head.cbtext1 bytes of text -typedef struct f_jour_pt_mid +struct f_jour_pt_mid { // this just seems to be a const FF FE FF char mid_tag[3]; unsigned char cbtext2; -} tag_f_jour_pt_mid; +}; // then 2*jour_pt_mid.cbtext2 bytes of wide text -typedef struct f_jour_pt_tail +struct f_jour_pt_tail { // 0=fastest // 1=shortest @@ -125,9 +126,9 @@ typedef struct f_jour_pt_tail int iunkn13; // 1 // ? size ? int iunkn14; // 30 -} tag_f_jour_pt_tail; +} ; -typedef struct f_jour_opts +struct f_jour_opts { // @00 short int siunkn0; @@ -232,9 +233,10 @@ typedef struct f_jour_opts // @166 int rest_dur_secs; int rest_interval_secs; -} tag_jour_opts; +} ; -typedef struct f_jour_opts_EUR_8 +// 56 bytes + struct f_jour_opts_EUR_8 { int iunkn38; int iunkn39; @@ -256,10 +258,11 @@ typedef struct f_jour_opts_EUR_8 // not in usa version8 int iunkn44; unsigned short int count_avoid_regions; -} tag_f_jour_opts_EUR_8; +} ; -// Also works for USA9 and USA11 -typedef struct f_jour_opts_EUR_10 +// 22 bytes +// Also works for USA9 and USA11 - and EUR9, EUR11 +struct f_jour_opts_EUR_10 { int iunkn38; int iunkn39; @@ -269,9 +272,10 @@ typedef struct f_jour_opts_EUR_10 int iunkn42; unsigned short int count_avoid_regions; -} tag_f_jour_opts_EUR_10; +}; -typedef struct f_jour_opts_USA_8 +// 52 bytes +struct f_jour_opts_USA_8 { int iunkn38; int iunkn39; @@ -291,9 +295,10 @@ typedef struct f_jour_opts_USA_8 int iunkn49; // @1a0 unsigned short int count_avoid_regions; -} tag_f_jour_opts_USA_8; +}; -typedef struct f_jour_opts_USA_10 +// 32 bytes +struct f_jour_opts_USA_10 { int iunkn38; int iunkn39; @@ -306,10 +311,10 @@ typedef struct f_jour_opts_USA_10 int iunkn43; int iunkn44; unsigned short int count_avoid_regions; -} tag_f_jour_opts_USA_10; +}; -typedef struct f_jour_avoid +struct f_jour_avoid { float x; float y; @@ -322,16 +327,16 @@ typedef struct f_jour_avoid int iunkn5; // avoid num? annot? int annot_num; -} tag_f_jour_avoid; +}; -typedef struct f_jour_trailer +struct f_jour_trailer { int iunkn0; // =0x65 int iunkn1; -} f_tag_jour_trailer; +}; -typedef struct jour_rtept +struct jour_rtept { int pthead_os; // mem owned by this struct, as buf does not have terminating null @@ -343,12 +348,12 @@ typedef struct jour_rtept // pointer to pushpin owned by pushpinlist struct pushpin* pushpin; char garmin_ident[7]; -} tag_jour_trept; +}; struct jour_rtept_rec * jour_rtept_rec_new(); void jour_rtept_rec_delete(struct jour_rtept_rec * jourpt_rec); -typedef struct journey +struct journey { int buf_len; char* buf; @@ -367,7 +372,7 @@ typedef struct journey // an array of ofsets to f_jour_avoid int * avoid_os_list; int trailer_os; -} tag_journey; +}; float scaled2deg(int scaled_deg); diff --git a/st2gpx/src/nannol.c b/st2gpx/src/nannol.c index f5f0dd91b..24573eee2 100644 --- a/st2gpx/src/nannol.c +++ b/st2gpx/src/nannol.c @@ -1,7 +1,8 @@ /* nannol.c - Extract data from MS Streets & Trips .est and Autoroute .axe files in GPX format. + Extract data from MS Streets & Trips .est, Autoroute .axe + and Mapoint .ptm files in GPX format. Copyright (C) 2003 James Sherring, james_sherring@yahoo.com @@ -29,12 +30,27 @@ #include #include #include +#include #include "gpx.h" #include "st2gpx.h" #include "annotations.h" -//static int readheight = 0; +#ifdef EXPLORE +#include "explore.h" +#endif + +int nullstrcmp(char* str1, char* str2) +{ + if ( (str1==NULL) && (str2==NULL) ) + return 0; + else if( (str1!=NULL) && (str2!=NULL) ) + return strcmp(str1, str2); + else if(str1==NULL) + return -1; + else + return 1; +} struct annot_rec * gpx2annot_line_rec(struct gpxpt** ptlist, int num_pts, int annot, int version) { @@ -74,6 +90,22 @@ struct annot_rec * gpx2annot_line_rec(struct gpxpt** ptlist, int num_pts, int an break; } + // If the last point is 'the same' as the first point, + // then set this as a closed-line. + // 'the same' means same name and epsilon-close + if( (nullstrcmp(ptlist[0]->name, ptlist[num_pts-1]->name) == 0) + && (fabs(ptlist[0]->lat - ptlist[num_pts-1]->lat) < 0.000001) + && (fabs(ptlist[0]->lon - ptlist[num_pts-1]->lon) < 0.000001) ) + { + // set the closed-line flag + *(unsigned char*)(rec->buf+line_offset-9) = 1; + + // So that the last point is only implicit + num_pts--; + + printf("Last point in a track or route is same as the first point, so removing last point and setting this as a closed line.\n"); + } + // set the annotation (record) number memcpy(rec->buf+4, &annot, 4); // set the number of points in the line diff --git a/st2gpx/src/ppinutil.c b/st2gpx/src/ppinutil.c index bd5ad6b42..1e99cf568 100644 --- a/st2gpx/src/ppinutil.c +++ b/st2gpx/src/ppinutil.c @@ -1,7 +1,8 @@ /* ppinutil.c - Extract data from MS Streets & Trips .est and Autoroute .axe files in GPX format. + Extract data from MS Streets & Trips .est, Autoroute .axe + and Mapoint .ptm files in GPX format. Copyright (C) 2003 James Sherring, james_sherring@yahoo.com @@ -34,9 +35,12 @@ #include "gpx.h" #include "st2gpx.h" #include "pushpins.h" - #include "ppinutil.h" +#ifdef EXPLORE +#include "explore.h" +#endif + struct pushpin_safelist * pushpin_safelist_new() { int i; @@ -289,87 +293,11 @@ struct pushpin_safelist * process_pushpin_file(char* ppin_in_file_name) i++; } - printf("Finished reading pushpins\n"); + if (opts.verbose_flag>2) + printf("Finished reading pushpins\n"); fflush(stdout); return ppplist; } -char std_udm1[6] = {18, 0, 0, 0, 0, 0}; -char std_udm2[1] = {1}; - -void explore_udm_data(struct pushpin_safelist * ppl) -{ - int i; - struct f_udm0_header * udm0_head=NULL; - struct f_udm0_header1 * udm0_head1=NULL; - struct f_udm0_ppin * udm0_ppin=NULL; - int expected_udm2_len=0; - - printf("Exploring UDM_Data from UserData\n"); - - // check UDM_Data[1] - if(ppl->UDM_Data_length[1] != 6) - printf("Unexpcted UDM_Data[1] length = %d, expected length 6\n", - ppl->UDM_Data_length[1]); - else - for(i=0; i<6; i++) - if(ppl->UDM_Data[1][i] != std_udm1[i]) - printf("UDM_Data[1][%d]=%#x, normally expect value %#x\n", - i, - (unsigned char)(ppl->UDM_Data[1][i]), - (unsigned char)(std_udm1[i])); - - // check UDM_Data[2] - if(ppl->UDM_Data_length[2] != 1) - printf("Unexpcted UDM_Data[2] length = %d, expected length 1\n", - ppl->UDM_Data_length[2]); - else - if(ppl->UDM_Data[2][0] != std_udm2[0]) - printf("UDM_Data[2][0]=%#x, normally expect value %#x\n", - (unsigned char)ppl->UDM_Data[2][0], - (unsigned char)(std_udm2[0])); - - // check UDM_Data[0] - - if (ppl->UDM_Data_length[0] < 14) - { - printf("UDM_Data[0] is too small to have a valid header\n"); - return; - } - - udm0_head = (struct f_udm0_header *)(ppl->UDM_Data[0]); - printf("There are %d highlighted pushpins\n", udm0_head->c_highlight_recs); - // list the highlighted udids? Nah. - - if(udm0_head->sunkn != 0x8001) - { - printf("Unexpected f_udm0_header:\n"); - printbuf(ppl->UDM_Data[0], sizeof(struct f_udm0_header)); - } - - udm0_head1 = (struct f_udm0_header1*) - (ppl->UDM_Data[0] + sizeof(struct f_udm0_header) - + 4*(udm0_head->c_highlight_recs)); - - if( udm0_head1->iunkn != 0) - printf("Unexpected f_udm0_header1->iunkn=%#x:\n",udm0_head1->iunkn); - - expected_udm2_len = (14 + 4*(udm0_head->c_highlight_recs) - + 6*(udm0_head1->c_format_records)); - if(ppl->UDM_Data_length[0] != expected_udm2_len) - printf("Unexpcted UDM_Data[0] length = %d, expected length %d for %d indicated format_records\n", - ppl->UDM_Data_length[0], expected_udm2_len, udm0_head1->c_format_records); - else - { - udm0_ppin = (struct f_udm0_ppin *)(ppl->UDM_Data[0] + 14 + 4*(udm0_head->c_highlight_recs) ); - // size has already been verified as (14 + 6 * udm0_head->c_format_records) - for(i=0; i<(udm0_head1->c_format_records); i++) - printf("udm0 ppin_rec[%d] has udid=%d, format=%#x, zorder=%d\n", - i, - udm0_ppin[i].ppin_udid, - udm0_ppin[i].format, - udm0_ppin[i].zorder); - } -} \ No newline at end of file diff --git a/st2gpx/src/ppinutil.h b/st2gpx/src/ppinutil.h index 9a6483071..f71689f68 100644 --- a/st2gpx/src/ppinutil.h +++ b/st2gpx/src/ppinutil.h @@ -1,7 +1,8 @@ /* ppinutil.h - Extract data from MS Streets & Trips .est and Autoroute .axe files in GPX format. + Extract data from MS Streets & Trips .est, Autoroute .axe + and Mapoint .ptm files in GPX format. Copyright (C) 2003 James Sherring, james_sherring@yahoo.com @@ -28,55 +29,28 @@ extern "C" { #endif -// The structures in UserData/UDM_Data for UDMId=0 -typedef struct f_udm0_header -{ - unsigned short int sunkn; // normally 0x8001 - int c_highlight_recs; -} tag_f_udm0_header; -// then c_highlight_recs ints with udid of highlighted ppin -typedef struct f_udm0_header1 -{ - int iunkn; // normally 0, probably indicates some array length to mess everything up - int c_format_records; -} tag_f_udm0_header1; -// then c_format_records of these: -typedef struct f_udm0_ppin -{ - int ppin_udid; - // 1 = show name + info - // (no record if name not shown?) - // 3 = show name - // 4 = upper left - // 8 = upper right - // 12 = lower left - // 16 = lower right - unsigned char format; - unsigned char zorder; -} tag_f_udm0_ppin; - -typedef struct pushpin_safelist +struct pushpin_safelist { struct pushpin ** pushpin_list; int num_pushpins; char * UDM_Data[3]; long UDM_Data_length[3]; -} tag_pushpin_safelist; +}; -typedef struct grid_point { +struct grid_point { long grid; long precision; -} tag_ms_point; +}; -typedef struct point { +struct point { double lon; double lat; -} tag_point; +}; // max size to be read from ppin memo fields #define MAX_PPIN_MEMO 1000 -typedef struct pushpin +struct pushpin { long UdId; int SetId; @@ -111,12 +85,12 @@ typedef struct pushpin char garmin_ident[7]; char* url; char* urlname; -} tag_pushpin; +} ; // not used yet -typedef struct pushpinset +struct pushpinset { int SetId; char* SetName; // max 128 @@ -139,7 +113,7 @@ typedef struct pushpinset char* DataSrcDescr; // memo char[30] CurrencyData; */ -} tag_pushpinset; +}; struct pushpin * pushpin_new(); void pushpin_delete(struct pushpin * pp); diff --git a/st2gpx/src/properties.c b/st2gpx/src/properties.c index 033706438..2bf6077c2 100644 --- a/st2gpx/src/properties.c +++ b/st2gpx/src/properties.c @@ -1,7 +1,8 @@ /* properties.c - Extract data from MS Streets & Trips .est and Autoroute .axe files in GPX format. + Extract data from MS Streets & Trips .est, Autoroute .axe + and Mapoint .ptm files in GPX format. Copyright (C) 2003 James Sherring, james_sherring@yahoo.com @@ -36,6 +37,10 @@ #include "st2gpx.h" #include "properties.h" +#ifdef EXPLORE +#include "explore.h" +#endif + #define OLE_PROP_STREAM ".Olhud5yvVwudb10uAaq5ezn4Ac" // some types from MS, as published at @@ -117,7 +122,7 @@ char * fmtid2str(char * str, char * fmtid) *(unsigned char*)(fmtid+13), *(unsigned char*)(fmtid+14), *(unsigned char*)(fmtid+15) ); - str[39]=0; + str[38]=0; return str; } @@ -166,7 +171,8 @@ struct dictionary * read_dictionary(int ents, char* buf, int bufsize) dict->ent_propid=(DWORD*)xmalloc(ents*sizeof(DWORD)); dict->ent_sz=(char**)xmalloc(ents*sizeof(char*)); - printf("reading %d entries from dictionary\n", ents); + if (opts.verbose_flag > 4) + printf("reading %d entries from dictionary\n", ents); while(ent_readent_cb == X->ent_sz -4) char ** ent_sz; // Zero-terminated string. Code page as indicated. -} tag_dictionary; +}; -typedef struct ole_property +struct ole_property { DWORD propid; DWORD dwType; // type tag int buflen; char* buf; -} tag_ole_property; +}; -typedef struct ole_property_set +struct ole_property_set { // FMTID fmtid ; // semantic name of a section char fmtid[16]; // semantic name of a section @@ -59,7 +60,7 @@ typedef struct ole_property_set unsigned int cProps; struct dictionary * dict; struct ole_property * pPropList; -} tag_ole_property_set; +}; struct ole_property_set * read_ole_properties(char* source_file_name, char* properties_file_name); void ole_property_set_delete(struct ole_property_set * props); diff --git a/st2gpx/src/pushpins.cpp b/st2gpx/src/pushpins.cpp index 77ff59a62..7efd2c90c 100644 --- a/st2gpx/src/pushpins.cpp +++ b/st2gpx/src/pushpins.cpp @@ -1,7 +1,8 @@ /* pushpins.cpp - Extract data from MS Streets & Trips .est and Autoroute .axe files in GPX format. + Extract data from MS Streets & Trips .est, Autoroute .axe + and Mapoint .ptm files in GPX format. Copyright (C) 2003 James Sherring, james_sherring@yahoo.com @@ -25,9 +26,9 @@ // for vt type values see http://www.canaimasoft.com/f90VB/OnlineManuals/UserManual/TH_99.htm //#import "c:\program files\common files\system\ado\msado15.dll" rename ( "EOF", "adoEOF" ) -//#import rename ( "EOF", "adoEOF" ) -#include "msado15.tlh" -#include "msado15.tli" +#import rename ( "EOF", "adoEOF" ) +//#include "msado15.tlh" +//#include "msado15.tli" #include #include // Include only once in your application @@ -40,7 +41,6 @@ #include "ppinutil.h" #include "contents.h" - struct InitOle { InitOle() { ::CoInitialize(NULL); } ~InitOle() { ::CoUninitialize(); } @@ -194,15 +194,16 @@ EXTERN_C struct pushpin_safelist * read_pushpins(char* ppin_file_name) int val_type=0; char * ppin_sql = NULL; char * UDM_sql = NULL; - char RenderData_buf[4]=""; + char RenderData_buf[8]=""; int RenderData_len=0; + short int NoteTypeId; ppplist->pushpin_list = (struct pushpin **)xmalloc(ppin_list_alloc_size*sizeof(struct pushpin *)); if (opts.st_version_num<9) - ppin_sql = "SELECT UD_Secondary.UdId, UD_Secondary.UdName, UD_Secondary.NoteShort, UD_Secondary.NoteLong, UD_Main.Grid, UD_Main.Precision, UD_Main.RenderData, UD_Main.MatchId, UD_Main.MOBBId FROM UD_Main INNER JOIN UD_Secondary ON UD_Main.UdId = UD_Secondary.UdId"; + ppin_sql = "SELECT UD_Secondary.UdId, UD_Secondary.UdName, UD_Secondary.NoteTypeId, UD_Secondary.NoteShort, UD_Secondary.NoteLong, UD_Main.Grid, UD_Main.Precision, UD_Main.RenderData, UD_Main.MatchId, UD_Main.MOBBId FROM UD_Main INNER JOIN UD_Secondary ON UD_Main.UdId = UD_Secondary.UdId;"; else - ppin_sql = "SELECT UdId, UdName, NoteShort, NoteLong, Grid, Precision, RenderData, MatchId, MOBBId FROM UD_Main"; + ppin_sql = "SELECT UdId, UdName, NoteTypeId, NoteShort, NoteLong, Grid, Precision, RenderData, MatchId, MOBBId FROM UD_Main;"; try { @@ -226,8 +227,8 @@ EXTERN_C struct pushpin_safelist * read_pushpins(char* ppin_file_name) hr = rs->Open(ppin_sql, cnstr, ADODB::adOpenForwardOnly, - ADODB::adLockReadOnly, - -1 ); + ADODB::adLockReadOnly, + ADODB::adCmdText ); while ((rs->adoEOF == FALSE)) { @@ -237,7 +238,14 @@ EXTERN_C struct pushpin_safelist * read_pushpins(char* ppin_file_name) variant2val(rs->Fields->GetItem("UdName")->Value, VT_BSTR,&(ppin->UdName), 0); variant2val(rs->Fields->GetItem("Grid")->Value, VT_I4, &(ppin->Grid), 0); variant2val(rs->Fields->GetItem("Precision")->Value,VT_I4, &(ppin->Precision), 0); - variant2val(rs->Fields->GetItem("NoteShort")->Value,VT_BSTR,&(ppin->NoteShort), 0); + variant2val(rs->Fields->GetItem("NoteTypeId")->Value,VT_I2, &NoteTypeId, 0); + + if(NoteTypeId==1) + variant2val(rs->Fields->GetItem("NoteShort")->Value,VT_BSTR,&(ppin->NoteShort), 0); + else if(NoteTypeId==2) + variant2val(rs->Fields->GetItem("NoteShort")->Value,VT_BSTR,&(ppin->NoteShort), 0); + else + printf("Unexpected NoteTypeId=%d for ppin udid=%d\n", NoteTypeId, ppin->UdId); RenderData_len = rs->Fields->GetItem("RenderData")->ActualSize; val_type = rs->Fields->GetItem("RenderData")->Value.vt; @@ -316,7 +324,7 @@ EXTERN_C struct pushpin_safelist * read_pushpins(char* ppin_file_name) cnstr, ADODB::adOpenForwardOnly, ADODB::adLockReadOnly, - -1 ); + ADODB::adCmdText); while ((rs->adoEOF == FALSE)) { @@ -331,8 +339,9 @@ EXTERN_C struct pushpin_safelist * read_pushpins(char* ppin_file_name) ppplist->UDM_Data[UdmDataId]=(char*)xmalloc(ppplist->UDM_Data_length[UdmDataId]); variant2val(rs->Fields->GetItem("UdmData")->Value, VT_ARRAY | VT_UI1, ppplist->UDM_Data[UdmDataId], ppplist->UDM_Data_length[UdmDataId] ); - printf("In UDM_Data table, for UdId=%d got %d bytes of data\n", - UdmDataId, ppplist->UDM_Data_length[UdmDataId]); + if(opts.verbose_flag > 3) + printf("In UDM_Data table, for UdId=%d got %d bytes of data\n", + UdmDataId, ppplist->UDM_Data_length[UdmDataId]); if (opts.explore_flag) { @@ -354,11 +363,12 @@ EXTERN_C struct pushpin_safelist * read_pushpins(char* ppin_file_name) catch( _com_error &e) { _bstr_t bstrSource(e.Source()); - _bstr_t bs = _bstr_t("*** Exception: ") + _bstr_t(e.Error()) + _bstr_t(" Msg: ") + _bstr_t bs = _bstr_t("*** Exception in read_pushpins(): ") + _bstr_t(e.Error()) + _bstr_t(" Msg: ") + _bstr_t(e.ErrorMessage()) + _bstr_t(" Description: ") + _bstr_t(e.Description()); wprintf(bs); + printf("\n"); _flushall(); if (opts.verbose_flag>4) @@ -407,7 +417,7 @@ EXTERN_C void write_pushpins_from_gpx(char* ppin_file_name, cnstr, ADODB::adOpenKeyset, ADODB::adLockOptimistic, - -1 ); + ADODB::adCmdText); variant2val(rs->Fields->GetItem("DbVersion")->Value, VT_I2, &DbVersion, 0); variant2val(rs->Fields->GetItem("LastSetId")->Value, VT_I4, &LastSetId, 0); @@ -446,13 +456,13 @@ EXTERN_C void write_pushpins_from_gpx(char* ppin_file_name, cnstr, ADODB::adOpenKeyset, ADODB::adLockOptimistic, - -1 ); + ADODB::adCmdText); hr = rs2.CreateInstance( __uuidof( ADODB::Recordset ) ); hr = rs2->Open(sql2, cnstr, ADODB::adOpenKeyset, ADODB::adLockOptimistic, - -1 ); + ADODB::adCmdText); } else { @@ -462,7 +472,7 @@ EXTERN_C void write_pushpins_from_gpx(char* ppin_file_name, cnstr, ADODB::adOpenKeyset, ADODB::adLockOptimistic, - -1 ); + ADODB::adCmdText); } @@ -473,6 +483,7 @@ EXTERN_C void write_pushpins_from_gpx(char* ppin_file_name, short int sizero=0; short int sione=1; short int sitwo=2; + short int notetype; // do for each wpt for(w=0; wwpt_list_count; w++) @@ -515,8 +526,22 @@ EXTERN_C void write_pushpins_from_gpx(char* ppin_file_name, rs2->Fields->GetItem("UdId" )->Value = val2variant(VT_I4, &thisUserDataId); rs2->Fields->GetItem("UdName" )->Value = val2variant(VT_BSTR,(gpt->name)); - rs2->Fields->GetItem("NoteTypeId")->Value = val2variant(VT_I2, &sione); - rs2->Fields->GetItem("NoteShort")->Value = val2variant(VT_BSTR,(gpt->desc)); + + if(gpt->desc == NULL) + { + notetype=1; + } + else if(strlen(gpt->desc) < 255) + { + notetype=1; + rs2->Fields->GetItem("NoteShort")->Value = val2variant(VT_BSTR,(gpt->desc)); + } + else + { + notetype=2; + rs2->Fields->GetItem("NoteLong")->Value = val2variant(VT_BSTR,(gpt->desc)); + } + rs2->Fields->GetItem("NoteTypeId")->Value = val2variant(VT_I2, ¬etype); rs2->Fields->GetItem("GeocodeHierarchy")->Value = val2variant(VT_I2, &sizero); rs2->Fields->GetItem("GeocodeContext" )->Value = val2variant(VT_I4, &lzero); // sometime I should support this @@ -550,8 +575,8 @@ EXTERN_C void write_pushpins_from_gpx(char* ppin_file_name, char* SetName = all_gpx->data_source_name; short int RenderMethod = 2; - short int GeocodeMethod = 5; - short int CreateMethod = 2; + short int GeocodeMethod = 3; //5; + short int CreateMethod = 1; // using 2 causes mp to crash short int GeometryType = 1; long UdCount=all_gpx->wpt_list_count; long MatchedCount=all_gpx->wpt_list_count; @@ -574,7 +599,7 @@ EXTERN_C void write_pushpins_from_gpx(char* ppin_file_name, cnstr, ADODB::adOpenKeyset, ADODB::adLockOptimistic, - -1 ); + ADODB::adCmdText); rs->AddNew(); @@ -637,11 +662,12 @@ EXTERN_C void write_pushpins_from_gpx(char* ppin_file_name, catch( _com_error &e) { _bstr_t bstrSource(e.Source()); - _bstr_t bs = _bstr_t("*** Exception: ") + _bstr_t(e.Error()) + _bstr_t(" Msg: ") + _bstr_t bs = _bstr_t("*** Exception in write_pushpins_from_gpx(): ") + _bstr_t(e.Error()) + _bstr_t(" Msg: ") + _bstr_t(e.ErrorMessage()) + _bstr_t(" Description: ") + _bstr_t(e.Description()); wprintf(bs); + printf("\n"); _flushall(); // if (opts.verbose_flag>4) diff --git a/st2gpx/src/pushpins.h b/st2gpx/src/pushpins.h index 425391cec..b6f486bf4 100644 --- a/st2gpx/src/pushpins.h +++ b/st2gpx/src/pushpins.h @@ -1,7 +1,8 @@ /* pushpins.h - Extract data from MS Streets & Trips .est and Autoroute .axe files in GPX format. + Extract data from MS Streets & Trips .est, Autoroute .axe + and Mapoint .ptm files in GPX format. Copyright (C) 2003 James Sherring, james_sherring@yahoo.com diff --git a/st2gpx/src/readgpx.c b/st2gpx/src/readgpx.c index a6ea04453..631a6cbe3 100644 --- a/st2gpx/src/readgpx.c +++ b/st2gpx/src/readgpx.c @@ -1,7 +1,8 @@ /* readgpx.c - Extract data from MS Streets & Trips .est and Autoroute .axe files in GPX format. + Extract data from MS Streets & Trips .est, Autoroute .axe + and Mapoint .ptm files in GPX format. Copyright (C) 2003 James Sherring, james_sherring@yahoo.com @@ -33,7 +34,6 @@ #include "gpx.h" #include "st2gpx.h" - typedef void (*gpx_elm_start_handler)(void *, const char *, const char **); typedef void (*gpx_elm_end_handler)(void *, const char *); @@ -611,8 +611,10 @@ void endtype(void *userData, const char *name) //sym_num=132; // traffic-light else if(strcmp(type_str, "Geocache|Unknown Cache")==0) sym_num=254; // question-mark - else if(strcmp(type_str, "Geocache|Micro Cache")==0) - sym_num=65; + else if(strcmp(type_str, "Geocache|Micro-Cache")==0) + sym_num=65; // rotor/X + else if(strcmp(type_str, "Geocache|Event Cache")==0) + sym_num=138; // knife & fork switch (current_main_element) { diff --git a/st2gpx/src/readmpst.c b/st2gpx/src/readmpst.c index 3a75d30cb..261761c30 100644 --- a/st2gpx/src/readmpst.c +++ b/st2gpx/src/readmpst.c @@ -1,7 +1,8 @@ /* readmpst.c - Extract data from MS Streets & Trips .est and Autoroute .axe files in GPX format. + Extract data from MS Streets & Trips .est, Autoroute .axe + and Mapoint .ptm files in GPX format. Copyright (C) 2003 James Sherring, james_sherring@yahoo.com diff --git a/st2gpx/src/st2gpx.c b/st2gpx/src/st2gpx.c index 0fc1d49d5..cd40d9ea5 100644 --- a/st2gpx/src/st2gpx.c +++ b/st2gpx/src/st2gpx.c @@ -1,7 +1,8 @@ /* st2gpx.c - Extract data from MS Streets & Trips .est and Autoroute .axe files in GPX format. + Extract data from MS Streets & Trips .est, Autoroute .axe + and Mapoint .ptm files in GPX format. Copyright (C) 2003 James Sherring, james_sherring@yahoo.com @@ -26,11 +27,12 @@ */ #include +#include #include #include #include #include - +#include #include #include @@ -139,6 +141,32 @@ char * strappend(char* str1, char* str2) return nw; } +char* buf2str(char* buf, int strlen) +// make a null-terminated string from a buf +{ + char*str=NULL; + if (strlen==0) + return NULL; + str=(char*)xmalloc(strlen+1); + memcpy(str, buf, strlen); + str[strlen]=0; + return str; +} + +char* buf2wstr(char* buf, int strlen) +// make a null-terminated wide string from a buf +// strlen is the number of characters, not len +{ + char*str=NULL; + if (strlen==0) + return NULL; + str=(char*)xmalloc(2*strlen+1); + memcpy(str, buf, 2*strlen); + str[2*strlen]=0; + str[2*strlen + 1]=0; + return str; +} + int readbytes(FILE* file, char* buf, int bytes2read) { int i; @@ -166,7 +194,7 @@ int readbytes(FILE* file, char* buf, int bytes2read) void show_usage() { - printf("st2gpx - Export data from MS Streets & Trips and Autoroute to GPX format\n\n"); + printf("st2gpx - Export data from MS Streets & Trips, Autoroute and Mappoint to GPX format\n\n"); // FIXME update this line printf("Usage: st2gpx [-hr] [-v verbose-level] [-g gpx-in-file] [-G gpx-out-file]"); printf(" [-m mpst-in-file] [-M pcx5-out-file] [-F st-mod-file] stfile\n\n"); @@ -198,11 +226,52 @@ void show_usage() void xsystem(char* syscmd) { int status; - printf("%s \n", syscmd); + int original_stderr; + char* tempname=NULL; + FILE* tempfile; + + if (opts.verbose_flag > 2) + printf("%s \n", syscmd); + else + { + // Throw away stderr from the system call. + // Actually, I just write it to a temp file. + original_stderr = _dup(2); // duplicate stderr + if( original_stderr == -1 ) + { + perror( "_dup( 2 ) failure" ); + exit( 1 ); + } + + tempname = tmpnam(tempname); + if( (tempname==NULL) || (( tempfile = fopen(tempname, "w") ) == NULL )) + { + puts( "Can't open tempfile for stderr\n" ); + exit( 1 ); + } + // stderr now refers to tempfile + if( -1 == _dup2( _fileno( tempfile ), 2 ) ) + { + perror( "Can't _dup2 stderr" ); + exit( 1 ); + } + } + _flushall(); status = system(syscmd); + + if (opts.verbose_flag < 3) + { + // restore stderr + fflush( tempfile ); + fflush( stderr ); + fclose( tempfile ); + _dup2( original_stderr, 2 ); + remove(tempname); + } + if (status) - fprintf(stderr, "system call returned an error\n"); + fprintf(stderr, "system call returned error %d\n", status); } main(int argc, char** argv) @@ -231,6 +300,8 @@ main(int argc, char** argv) char cmdext[_MAX_EXT]; char * cmdpath=NULL; + char file1[_MAX_PATH]; + char file2[_MAX_PATH]; struct pushpin_safelist* ppplist=NULL; struct journey* jour=NULL; @@ -253,7 +324,7 @@ main(int argc, char** argv) #ifdef MEMCHK // Call _CrtCheckMemory at every allocation and deallocation request. - SET_CRT_DEBUG_FIELD(_CRTDBG_CHECK_ALWAYS_DF); +// SET_CRT_DEBUG_FIELD(_CRTDBG_CHECK_ALWAYS_DF); // Keep freed memory blocks in the heaps linked list, assign them the _FREE_BLOCK type, // and fill them with the byte value 0xDD. SET_CRT_DEBUG_FIELD(_CRTDBG_DELAY_FREE_MEM_DF); @@ -272,8 +343,8 @@ main(int argc, char** argv) _CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDOUT ); #endif - // _CrtSetBreakAlloc(136); - + // Set this to find where leaking mem was allocated + //_CrtSetBreakAlloc(209); while (1) { @@ -399,7 +470,7 @@ main(int argc, char** argv) opts.source_file_name = (char*)xmalloc(strlen(argv[optind])+1); strcpy(opts.source_file_name, argv[optind]); if (opts.verbose_flag > 1) - printf("Analysing autoroute file %s\n\n", opts.source_file_name); + printf("Analysing MS Map file %s\n\n", opts.source_file_name); if (ppin_in_file_name==NULL) ppin_in_file_name = strappend(opts.source_file_name, ".Contents\\UserData.mdb"); if (jour_in_file_name==NULL) @@ -413,12 +484,11 @@ main(int argc, char** argv) { printf("Unrecognised option %s\n", argv[optind+1]); show_usage(); - } else { if (opts.verbose_flag > 1) - printf("Not analysing any core S&T or autoroute file\n"); + printf("Not analysing any core MS Map file\n"); } if (opts.source_file_name) @@ -428,9 +498,7 @@ main(int argc, char** argv) // Find the path for istorage from the path in argv[0] - // this is not ANSI _splitpath(argv[0], cmddrv, cmddir, cmdfilename, cmdext); - //sprintf(cmdpath, "%s%s", cmddrv, cmddir); cmdpath = strappend(cmddrv, cmddir); _fullpath(source_full_path, opts.source_file_name, _MAX_PATH); @@ -438,11 +506,9 @@ main(int argc, char** argv) sprintf(syscmd, "%sistorage\\istorage.exe \"%s\"", cmdpath, source_full_path); xsystem(syscmd); - printf("*****************************************************************\n"); - printf("Finished istorage command\n"); - - sprintf(syscmd, "rename \"%s.Contents\\UserData.\" UserData.mdb", opts.source_file_name); - xsystem(syscmd); + sprintf(file1, "%s.Contents\\UserData.", opts.source_file_name); + sprintf(file2, "%s.Contents\\UserData.mdb", opts.source_file_name); + rename(file1, file2); } // *************************** @@ -456,7 +522,7 @@ main(int argc, char** argv) if (all_gpx==NULL) printf("Didn't read any usable data from %s ???\n",gpx_in_file_name); printf("Read %d waypoints, %d routes and %d tracks from file %s\n", all_gpx->wpt_list_count, all_gpx->rte_list_count, all_gpx->trk_list_count, gpx_in_file_name); - printf("Importing this data as %d lines\n", all_gpx->rte_list_count + all_gpx->trk_list_count); + printf("Importing this data as %d pushpins and %d lines\n", all_gpx->wpt_list_count, all_gpx->rte_list_count + all_gpx->trk_list_count); } // Read Mapsource text-export file. @@ -470,11 +536,12 @@ main(int argc, char** argv) printf("Read %d waypoints, %d routes and %d tracks from file %s\n", all_gpx->wpt_list_count, all_gpx->rte_list_count, all_gpx->trk_list_count, mpst_in_file_name); - printf("Importing this data as %d lines\n", + printf("Importing this data as %d pushpins and %d lines\n", + all_gpx->wpt_list_count, all_gpx->rte_list_count + all_gpx->trk_list_count); } - // ole properties from S&T source file + // ole properties from S&T/Autoreoute/Mappoint source file if (opts.source_file_name) { strips_properties=read_ole_properties(opts.source_file_name, NULL); @@ -482,7 +549,7 @@ main(int argc, char** argv) if ((prop!=NULL) && (prop->buf != NULL) ) { opts.st_version_num = *(int*)(prop->buf); - printf("Autoroute/S&T version in %s is %d\n", opts.source_file_name, opts.st_version_num); + printf("MS Map version in %s is %d\n", opts.source_file_name, opts.st_version_num); } prop = get_propterty(strips_properties, 0x10000); if ((prop!=NULL) && (prop->buf != NULL) ) @@ -533,26 +600,20 @@ main(int argc, char** argv) if (annots==NULL) printf("After merging data, dont have any annotations???\n"); printf("After merging data, there are %d annotations\n", annots->num_annotations); - //print_annotations(annots); write_annotations(annots, annot_in_file_name); - //print_annotations(annots); - // ******************** - // This is experimantal - // ******************** - temp_str = strappend(opts.source_file_name, ".Contents\\Contents"); - write_pushpins_from_gpx(ppin_in_file_name, all_gpx, conts, temp_str); - free(temp_str); - temp_str=NULL; + sprintf(file1, "%s.Contents\\Contents", opts.source_file_name); + write_pushpins_from_gpx(ppin_in_file_name, all_gpx, conts, file1); } - // create the s&t/autoroute file from the modified parts + // create the s&t/autoroute/mappoint file from the modified parts if ((opts.source_file_name!=NULL) && (all_gpx!=NULL) && (import_file_name!=NULL)) { // Actually, we should allow NULL import_file_name and invent a sensible name - sprintf(syscmd, "rename %s.Contents\\UserData.mdb UserData.", opts.source_file_name); - xsystem(syscmd); + sprintf(file1, "%s.Contents\\UserData.mdb", opts.source_file_name); + sprintf(file2, "%s.Contents\\UserData.", opts.source_file_name); + rename(file1, file2); contents_dir_name=(char*)xmalloc(strlen(opts.source_file_name)+20); sprintf(contents_dir_name, "%s.Contents", opts.source_file_name); @@ -562,27 +623,22 @@ main(int argc, char** argv) sprintf(syscmd, "%sistorage\\istorage-make.exe \"%s\"", cmdpath, contents_full_path); xsystem(syscmd); - printf("*****************************************************************\n"); - printf("Finished istorage-make command\n"); - - sprintf(syscmd, "del \"%s\"", import_file_name); - xsystem(syscmd); + remove(import_file_name); _splitpath(opts.source_file_name, cmddrv, cmddir, cmdfilename, cmdext); - sprintf(syscmd, "move \"%s.Contents.ole\" \"%s\"", opts.source_file_name, import_file_name); - xsystem(syscmd); - + sprintf(file1, "%s.Contents.ole", opts.source_file_name); + rename(file1, import_file_name); } // Clean up the compound file directory if (opts.source_file_name) { { - sprintf(syscmd, "echo y|del \"%s.Contents\"", opts.source_file_name); + sprintf(syscmd, "echo y|del \"%s.Contents\" > null", opts.source_file_name); xsystem(syscmd); - sprintf(syscmd, "rmdir \"%s.Contents\"", opts.source_file_name); - xsystem(syscmd); + sprintf(file1, "%s.Contents", opts.source_file_name); + _rmdir(file1); } } @@ -609,14 +665,11 @@ main(int argc, char** argv) if (opts.verbose_flag>5) printf("Done freeing all\n"); - //debug_show_sizes(); - //debug_pause(); - //printf("exiting main\n"); - _flushall(); -#ifdef _DEBUG +//#ifdef _DEBUG // _CrtDumpMemoryLeaks(); -#endif +//#endif + printf("All done.\n"); debug_pause(); } diff --git a/st2gpx/src/st2gpx.dsp b/st2gpx/src/st2gpx.dsp deleted file mode 100644 index d47124a70..000000000 --- a/st2gpx/src/st2gpx.dsp +++ /dev/null @@ -1,220 +0,0 @@ -# Microsoft Developer Studio Project File - Name="st2gpx" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=st2gpx - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "st2gpx.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "st2gpx.mak" CFG="st2gpx - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "st2gpx - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "st2gpx - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "st2gpx - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /Zp1 /Za /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 libexpat.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# SUBTRACT LINK32 /debug - -!ELSEIF "$(CFG)" == "st2gpx - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /Zp1 /Za /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 libexpat.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# SUBTRACT LINK32 /profile /map - -!ENDIF - -# Begin Target - -# Name "st2gpx - Win32 Release" -# Name "st2gpx - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\annotations.c -# End Source File -# Begin Source File - -SOURCE=.\contents.c - -!IF "$(CFG)" == "st2gpx - Win32 Release" - -!ELSEIF "$(CFG)" == "st2gpx - Win32 Debug" - -# ADD CPP /Za - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\debug.c -# End Source File -# Begin Source File - -SOURCE=.\getopt.c -# ADD CPP /Ze -# End Source File -# Begin Source File - -SOURCE=.\journey.c -# End Source File -# Begin Source File - -SOURCE=.\nannol.c -# End Source File -# Begin Source File - -SOURCE=.\ppinutil.c -# End Source File -# Begin Source File - -SOURCE=.\properties.c -# ADD CPP /Ze -# End Source File -# Begin Source File - -SOURCE=.\pushpins.cpp -# ADD CPP /Ze -# End Source File -# Begin Source File - -SOURCE=.\readgpx.c -# End Source File -# Begin Source File - -SOURCE=.\readmpst.c -# End Source File -# Begin Source File - -SOURCE=.\st2gpx.c -# End Source File -# Begin Source File - -SOURCE=.\writegpx.c -# End Source File -# Begin Source File - -SOURCE=.\writepcx.c -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=.\annotations.h -# End Source File -# Begin Source File - -SOURCE=.\contents.h -# End Source File -# Begin Source File - -SOURCE=.\getopt.h -# End Source File -# Begin Source File - -SOURCE=.\gpx.h -# End Source File -# Begin Source File - -SOURCE=.\journey.h -# End Source File -# Begin Source File - -SOURCE=.\ppinutil.h -# End Source File -# Begin Source File - -SOURCE=.\properties.h -# End Source File -# Begin Source File - -SOURCE=.\pushpins.h -# End Source File -# Begin Source File - -SOURCE=.\st2gpx.h -# End Source File -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# Begin Source File - -SOURCE=.\bugs.txt -# End Source File -# Begin Source File - -SOURCE=.\build.txt -# End Source File -# Begin Source File - -SOURCE=.\history.txt -# End Source File -# Begin Source File - -SOURCE=.\ToDo.txt -# End Source File -# End Target -# End Project diff --git a/st2gpx/src/st2gpx.h b/st2gpx/src/st2gpx.h index 670e3e1a3..c1fb04900 100644 --- a/st2gpx/src/st2gpx.h +++ b/st2gpx/src/st2gpx.h @@ -1,7 +1,8 @@ /* st2gpx.h - Extract data from MS Streets & Trips .est and Autoroute .axe files in GPX format. + Extract data from MS Streets & Trips .est, Autoroute .axe + and Mapoint .ptm files in GPX format. Copyright (C) 2003 James Sherring, james_sherring@yahoo.com @@ -28,9 +29,9 @@ extern "C" { #endif +//#define EXPLORE #ifdef _DEBUG - #define MEMCHK #define DEBUG_STDOUT @@ -48,7 +49,7 @@ extern "C" { typedef unsigned short WCHAR; -typedef struct st2gpx_options +struct st2gpx_options { // 0 - only errors // 1 also the structured data output, e.g. line point info @@ -69,7 +70,7 @@ typedef struct st2gpx_options // 0 for EUR, i.e. Autoroute // 1 for USA, i,e, Streets & Trips unsigned char isUSA; -} tag_st2gpx_options; +}; // FIXME is this the correct way to forward define these? @@ -81,17 +82,7 @@ extern struct annotations; extern struct pushpin_safelist; extern struct annot_rec ; extern struct gpx_data; -extern struct f_jour_pt_head; -extern struct f_jour_pt_tail; -extern struct f_jour_opts_EUR_8; -extern struct f_jour_opts_EUR_10; -extern struct f_jour_opts_USA_8; -extern struct f_jour_opts_USA_10; -extern struct f_jour_opts; -extern struct f_jour_avoid; -extern struct f_jour_trailer; extern struct journey; -extern struct f_jour_header; extern struct contents; #endif // __cplusplus @@ -101,7 +92,9 @@ extern struct st2gpx_options opts; void * xmalloc(size_t size); void * xrealloc(void* ptr, size_t size); char * str2ascii(char* str); -char * strappend(char* str1, char* str2); +char * strappend(char* str1, char* str2); +char * buf2str(char* buf, int strlen); +char * buf2wstr(char* buf, int strlen); int readbytes(FILE* file, char* buf, int bytes2read); //nannol.c struct annotations * merge_gpx_annot(struct annotations * annots, struct gpx_data* all_gpx); @@ -111,19 +104,6 @@ void pcx5_export(char* pcx5_out_file_name, struct pushpin_safelist * ppplist, st //debug.c void debug_pause(); void printbuf(char* buf, int len); -void explore_annot(struct annot_rec * rec); -void print_f_jour_header(struct f_jour_header * head); -void print_f_jour_pt_head(struct f_jour_pt_head * pt_head); -void print_f_jour_pt_tail(struct f_jour_pt_tail * pt_tail); -void print_f_jour_opts(struct f_jour_opts * jopts); -void print_f_jour_opts_EUR_8(struct f_jour_opts_EUR_8 * jopts); -void print_f_jour_opts_EUR_10(struct f_jour_opts_EUR_10 * jopts); -void print_f_jour_opts_USA_8(struct f_jour_opts_USA_8 * jopts); -void print_f_jour_opts_USA_10(struct f_jour_opts_USA_10 * jopts); -void print_f_jour_avoid(struct f_jour_avoid * avoid); -void print_f_jour_trailer(struct f_jour_trailer * trailer); -void print_annot_rec(struct annot_rec * rec); -void print_annotations(struct annotations * annots); void debug_show_sizes(); //st2gpx.c struct gpx_data * read_mpstext(char* mpstxt_file_name); diff --git a/st2gpx/src/st2gpx.sln b/st2gpx/src/st2gpx.sln new file mode 100644 index 000000000..a90954698 --- /dev/null +++ b/st2gpx/src/st2gpx.sln @@ -0,0 +1,21 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "st2gpx", "st2gpx.vcproj", "{3D8C8F70-1814-4424-99FF-F52C7B74C77A}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {3D8C8F70-1814-4424-99FF-F52C7B74C77A}.Debug.ActiveCfg = Debug|Win32 + {3D8C8F70-1814-4424-99FF-F52C7B74C77A}.Debug.Build.0 = Debug|Win32 + {3D8C8F70-1814-4424-99FF-F52C7B74C77A}.Release.ActiveCfg = Release|Win32 + {3D8C8F70-1814-4424-99FF-F52C7B74C77A}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/st2gpx/src/st2gpx.vcproj b/st2gpx/src/st2gpx.vcproj new file mode 100644 index 000000000..1c66f978f --- /dev/null +++ b/st2gpx/src/st2gpx.vcproj @@ -0,0 +1,472 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/st2gpx/src/writegpx.c b/st2gpx/src/writegpx.c index b0bd690bf..701433aaa 100644 --- a/st2gpx/src/writegpx.c +++ b/st2gpx/src/writegpx.c @@ -1,7 +1,8 @@ /* writegpx.c - Extract data from MS Streets & Trips .est and Autoroute .axe files in GPX format. + Extract data from MS Streets & Trips .est, Autoroute .axe + and Mapoint .ptm files in GPX format. Copyright (C) 2003 James Sherring, james_sherring@yahoo.com @@ -44,6 +45,9 @@ #define GPX_TRKPT 2 char * gpxptypelabel[3] = {"wpt", "rtept", "trkpt"}; +// Sequential numbering of track-points +int pt_num; + FILE* gpx_open_write_file_header(char* gpx_out_file_name) { FILE* gpx_out_file=NULL; @@ -189,28 +193,19 @@ void gpx_write_pushpinlist (FILE* gpx_out_file, struct pushpin_safelist *ppplist { int i; struct gpxpt * pt=NULL; -// char* opt_elms; -// int optlen; if ((gpx_out_file==NULL) || (ppplist==NULL)) return; pt = gpxpt_new(); - printf("writting gpx waypoints for %d pushpins\n", ppplist->num_pushpins); + printf("writing gpx waypoints for %d pushpins\n", ppplist->num_pushpins); for (i=0; inum_pushpins; i++) { if (ppplist->pushpin_list[i]==NULL) break; -// optlen = strlen(ppplist->pushpin_list[i]->UdName) -// + strlen(ppplist->pushpin_list[i]->NoteShort) + 60; -// opt_elms = (char*)xmalloc(optlen); - -// sprintf(opt_elms, "", -// ppplist->pushpin_list[i]->UdName, ppplist->pushpin_list[i]->NoteShort); - pt->name = _strdup(ppplist->pushpin_list[i]->UdName); pt->desc = _strdup(ppplist->pushpin_list[i]->NoteShort); @@ -220,7 +215,6 @@ void gpx_write_pushpinlist (FILE* gpx_out_file, struct pushpin_safelist *ppplist pt->symbol = ppplist->pushpin_list[i]->RenderData; gpx_write_point(gpx_out_file, pt, GPX_WPT); -// free(opt_elms); free(pt->name); pt->name=NULL; free(pt->desc); @@ -230,12 +224,15 @@ void gpx_write_pushpinlist (FILE* gpx_out_file, struct pushpin_safelist *ppplist gpxpt_delete(pt); } -void gpx_write_annot_rec(FILE* gpx_out_file, struct annot_rec * rec) +void gpx_write_annot_rec(FILE* gpx_out_file, struct annot_rec * rec, int annot_version) { int pt_type; int p; -// char opt_elms[200]; - struct gpxpt * pt; + struct gpxpt * pt=NULL; + struct gpxpt * first_point = NULL; + int point_os; + int data_os; + int c_shape_points; if ( (gpx_out_file==NULL) || (rec==NULL) ) { @@ -276,10 +273,17 @@ void gpx_write_annot_rec(FILE* gpx_out_file, struct annot_rec * rec) // ******************* - for (p=0; p < rec->line_points; p++) + for (p=0; p < rec->line_points; p++, pt_num++) { pt=gpx_get_point(rec->buf + rec->line_offset + 12*p); - pt->name=(char*)xmalloc(7); + // I wanted to keep pt names less that 6 chars, + // but there can be large polylines e.g with more than 30,000 pts + if(pt_num>9999999) + { + printf("Too many points\n"); + exit(0); + } + pt->name=(char*)xmalloc(10); if(pt==NULL) { printf("got null pt #%p in annotation %d, skipping more points in this annotation\n", @@ -287,17 +291,23 @@ void gpx_write_annot_rec(FILE* gpx_out_file, struct annot_rec * rec) break; } if(opts.use_gpx_route) - sprintf(pt->name, "rp%04d", p); - //sprintf(opt_elms, "rp%04d", p); + sprintf(pt->name, "rp%04d", pt_num); else // we need to include a name for trackpoints // for them to be recognised by easygps. - sprintf(pt->name, "tp%04d", p); - //sprintf(opt_elms, "tp%04d", p); + sprintf(pt->name, "tp%04d", pt_num); gpx_write_point(gpx_out_file, pt, pt_type); + if(p==0) + first_point = gpxpt_copy(pt); gpxpt_delete(pt); } - + + // If this is a closed poly-line, then add the first point + // as the implicit last point. + if(rec->is_closed_line_flag) + gpx_write_point(gpx_out_file, first_point, pt_type); + gpxpt_delete(first_point); + // ******************** // rte or trk trailer // ******************** @@ -306,10 +316,94 @@ void gpx_write_annot_rec(FILE* gpx_out_file, struct annot_rec * rec) fprintf(gpx_out_file, "\t\n"); else fprintf(gpx_out_file, "\t\t\n\t\n"); + + break; case ANNOT_TYPE_OVAL: - case ANNOT_TYPE_TEXT: case ANNOT_TYPE_CIRCLE: + + if (annot_version==3) + { + data_os=ANNOT_RECOS_TEXT; + // FIXME get this from buf + c_shape_points=61; + point_os = ANNOT_RECOS_OVAL_POINTOS; + } + else if (annot_version==4) + { + data_os=ANNOT_RECOS_TEXT + 4; + point_os = ANNOT_RECOS_OVAL_POINTOS + 4; + c_shape_points=33; + } + else + { + printf("Unexpected annotation version %d\n", annot_version); + return; + } + + //otail = (struct f_annotation_oval_tail *)(rec->buf + data_os); + + // ************ + // trk header + // ************ + + fprintf(gpx_out_file, "\t\n"); + + fprintf(gpx_out_file, "\t\t"); + if (rec->text==NULL) + fprintf(gpx_out_file, "TK%04d\n", rec->annot_num); + else + fprintf(gpx_out_file, rec->text); + fprintf(gpx_out_file, "\n"); + + fprintf(gpx_out_file, "\t\tExtracted from Annotation %d (%s)\n", + rec->annot_num, annot_type_name[rec->type]); + fprintf(gpx_out_file, "\t\t\n"); + + // ************ + // trk points + // ************ + + for (p=0; p < c_shape_points; p++, pt_num++) + { + pt=gpx_get_point(rec->buf + point_os + 12*p); + // I wanted to keep pt names less that 6 chars, + // but there can be large polylines e.g with more than 30,000 pts + if(pt_num>9999999) + { + printf("Too many points\n"); + exit(0); + } + pt->name=(char*)xmalloc(10); + if(pt==NULL) + { + printf("got null pt #%p in annotation %d, skipping more points in this annotation\n", + p, rec->annot_num); + break; + } + if(opts.use_gpx_route) + sprintf(pt->name, "rp%04d", pt_num); + else + // we need to include a name for trackpoints + // for them to be recognised by easygps. + sprintf(pt->name, "tp%04d", pt_num); + gpx_write_point(gpx_out_file, pt, pt_type); + if(p==0) + first_point = gpxpt_copy(pt); + gpxpt_delete(pt); + } + //close the loop + gpx_write_point(gpx_out_file, first_point, pt_type); + gpxpt_delete(first_point); + + // ************* + // trk trailer + // ************* + + fprintf(gpx_out_file, "\t\t\n\t\n"); + + break; + case ANNOT_TYPE_TEXT: default: break; } @@ -318,10 +412,19 @@ void gpx_write_annot_rec(FILE* gpx_out_file, struct annot_rec * rec) void gpx_write_annotations(FILE* gpx_out_file, struct annotations * annots) { int i; + + if(annots->num_annotations == 0) + return; + + if(opts.use_gpx_route) + printf("writing gpx routes for %d annotations\n", annots->num_annotations); + else + printf("writing gpx tracks for %d annotations\n", annots->num_annotations); + if ( (gpx_out_file!=NULL) && (annots!=NULL) ) for (i=0; i < annots->num_annotations; i++) { - gpx_write_annot_rec(gpx_out_file, annots->annot_list[i]); + gpx_write_annot_rec(gpx_out_file, annots->annot_list[i], annots->version); } } @@ -334,6 +437,7 @@ void gpx_write_all(char* gpx_out_file_name, if ( (ppplist==NULL) && (jour==NULL) && (annots==NULL) ) return; gpx_out_file = gpx_open_write_file_header(gpx_out_file_name); + pt_num=0; gpx_write_pushpinlist(gpx_out_file, ppplist); gpx_write_journey(gpx_out_file, jour); gpx_write_annotations(gpx_out_file, annots); diff --git a/st2gpx/src/writepcx.c b/st2gpx/src/writepcx.c index 35e54b6e6..4c18d8246 100644 --- a/st2gpx/src/writepcx.c +++ b/st2gpx/src/writepcx.c @@ -1,7 +1,8 @@ /* writepcx.c - Extract data from MS Streets & Trips .est and Autoroute .axe files in GPX format. + Extract data from MS Streets & Trips .est, Autoroute .axe + and Mapoint .ptm files in GPX format. Copyright (C) 2003 James Sherring, james_sherring@yahoo.com @@ -309,7 +310,8 @@ void pcx5_write_ppin(FILE* file, struct pushpin * ppin) // FIXME this should come from the pushpin icon int symbol=8; // or 18 - strpad(timedate, 19); + // 18 or 19? + strpad(timedate, 18); // Should I create a meaningful note if there is none? if(ppin->NoteShort) @@ -338,7 +340,7 @@ void pcx5_write_jour_pt(FILE* file, struct journey * jour, struct jour_rtept * r { char timedate[19]=""; float alt=0; - char desc[40]; + char desc[41]; float proximity=0; int symbol=8; // or 18 @@ -348,7 +350,7 @@ void pcx5_write_jour_pt(FILE* file, struct journey * jour, struct jour_rtept * r // { f_wpt_head = (struct f_jour_pt_head *)(jour->buf + (rtept->pthead_os)); - strpad(timedate, 19); + strpad(timedate, 18); memcpy(desc, rtept->text1,39); strpad(desc, 40); @@ -409,7 +411,8 @@ void pcx5_write_annot_line(FILE* file, struct annot_rec * pannot) fprintf(file, "\n"); fprintf(file, GAR_TRK_HEADER); - strpad(timedate, 19); + // fixme - 18/19 + strpad(timedate, 18); for(p=0; pline_points; p++) { -- 2.30.2